OLD | NEW |
---|---|
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library analyzer.src.generated.declaration_resolver; | 5 library analyzer.src.generated.declaration_resolver; |
6 | 6 |
7 import 'package:analyzer/dart/ast/ast.dart'; | 7 import 'package:analyzer/dart/ast/ast.dart'; |
8 import 'package:analyzer/dart/ast/token.dart'; | 8 import 'package:analyzer/dart/ast/token.dart'; |
9 import 'package:analyzer/dart/ast/visitor.dart'; | 9 import 'package:analyzer/dart/ast/visitor.dart'; |
10 import 'package:analyzer/dart/element/element.dart'; | 10 import 'package:analyzer/dart/element/element.dart'; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
57 // Annotations can only contain elements in certain erroneous situations, | 57 // Annotations can only contain elements in certain erroneous situations, |
58 // in which case the elements are disconnected from the rest of the element | 58 // in which case the elements are disconnected from the rest of the element |
59 // model, thus we can't reconnect to them. To avoid crashes, just create | 59 // model, thus we can't reconnect to them. To avoid crashes, just create |
60 // fresh elements. | 60 // fresh elements. |
61 ElementHolder elementHolder = new ElementHolder(); | 61 ElementHolder elementHolder = new ElementHolder(); |
62 new ElementBuilder(elementHolder, _enclosingUnit).visitAnnotation(node); | 62 new ElementBuilder(elementHolder, _enclosingUnit).visitAnnotation(node); |
63 return null; | 63 return null; |
64 } | 64 } |
65 | 65 |
66 @override | 66 @override |
67 Object visitBlockFunctionBody(BlockFunctionBody node) { | |
68 if (_isBodyToCreateElementsFor(node)) { | |
69 _walker.consumeLocalElements(); | |
70 node.accept(_walker.elementBuilder); | |
71 return null; | |
72 } else { | |
73 return super.visitBlockFunctionBody(node); | |
74 } | |
75 } | |
76 | |
77 @override | |
67 Object visitCatchClause(CatchClause node) { | 78 Object visitCatchClause(CatchClause node) { |
68 _walker.elementBuilder.buildCatchVariableElements(node); | 79 _walker.elementBuilder.buildCatchVariableElements(node); |
69 return super.visitCatchClause(node); | 80 return super.visitCatchClause(node); |
70 } | 81 } |
71 | 82 |
72 @override | 83 @override |
73 Object visitClassDeclaration(ClassDeclaration node) { | 84 Object visitClassDeclaration(ClassDeclaration node) { |
74 ClassElement element = _match(node.name, _walker.getClass()); | 85 ClassElement element = _match(node.name, _walker.getClass()); |
75 _walk(new ElementWalker.forClass(element), () { | 86 _walk(new ElementWalker.forClass(element), () { |
76 super.visitClassDeclaration(node); | 87 super.visitClassDeclaration(node); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
142 | 153 |
143 @override | 154 @override |
144 Object visitExportDirective(ExportDirective node) { | 155 Object visitExportDirective(ExportDirective node) { |
145 super.visitExportDirective(node); | 156 super.visitExportDirective(node); |
146 _resolveAnnotations( | 157 _resolveAnnotations( |
147 node, node.metadata, _enclosingUnit.getAnnotations(node.offset)); | 158 node, node.metadata, _enclosingUnit.getAnnotations(node.offset)); |
148 return null; | 159 return null; |
149 } | 160 } |
150 | 161 |
151 @override | 162 @override |
163 Object visitExpressionFunctionBody(ExpressionFunctionBody node) { | |
164 if (_isBodyToCreateElementsFor(node)) { | |
165 _walker.consumeLocalElements(); | |
166 node.accept(_walker.elementBuilder); | |
167 return null; | |
168 } else { | |
169 return super.visitExpressionFunctionBody(node); | |
170 } | |
171 } | |
172 | |
173 @override | |
152 Object visitFieldDeclaration(FieldDeclaration node) { | 174 Object visitFieldDeclaration(FieldDeclaration node) { |
153 super.visitFieldDeclaration(node); | 175 super.visitFieldDeclaration(node); |
154 _resolveMetadata(node, node.metadata, node.fields.variables[0].element); | 176 _resolveMetadata(node, node.metadata, node.fields.variables[0].element); |
155 return null; | 177 return null; |
156 } | 178 } |
157 | 179 |
158 @override | 180 @override |
159 Object visitFieldFormalParameter(FieldFormalParameter node) { | 181 Object visitFieldFormalParameter(FieldFormalParameter node) { |
160 if (node.parent is! DefaultFormalParameter) { | 182 if (node.parent is! DefaultFormalParameter) { |
161 ParameterElement element = | 183 ParameterElement element = |
(...skipping 20 matching lines...) Expand all Loading... | |
182 element = _match(functionName, _walker.getFunction()); | 204 element = _match(functionName, _walker.getFunction()); |
183 } else if (property.keyword == Keyword.GET) { | 205 } else if (property.keyword == Keyword.GET) { |
184 element = _match(functionName, _walker.getAccessor()); | 206 element = _match(functionName, _walker.getAccessor()); |
185 } else { | 207 } else { |
186 assert(property.keyword == Keyword.SET); | 208 assert(property.keyword == Keyword.SET); |
187 element = _match(functionName, _walker.getAccessor(), | 209 element = _match(functionName, _walker.getAccessor(), |
188 elementName: functionName.name + '='); | 210 elementName: functionName.name + '='); |
189 } | 211 } |
190 } | 212 } |
191 node.functionExpression.element = element; | 213 node.functionExpression.element = element; |
214 _walker._elementHolder?.addFunction(element); | |
192 _walk(new ElementWalker.forExecutable(element, _enclosingUnit), () { | 215 _walk(new ElementWalker.forExecutable(element, _enclosingUnit), () { |
193 super.visitFunctionDeclaration(node); | 216 super.visitFunctionDeclaration(node); |
194 }); | 217 }); |
195 _resolveMetadata(node, node.metadata, element); | 218 _resolveMetadata(node, node.metadata, element); |
196 return null; | 219 return null; |
197 } | 220 } |
198 | 221 |
199 @override | 222 @override |
200 Object visitFunctionExpression(FunctionExpression node) { | 223 Object visitFunctionExpression(FunctionExpression node) { |
201 if (node.parent is! FunctionDeclaration) { | 224 if (node.parent is! FunctionDeclaration) { |
202 FunctionElement element = _walker.getFunction(); | 225 FunctionElement element = _walker.getFunction(); |
203 _matchOffset(element, node.offset); | 226 _matchOffset(element, node.offset); |
204 node.element = element; | 227 node.element = element; |
228 _walker._elementHolder.addFunction(element); | |
Brian Wilkerson
2016/11/08 21:12:08
Is it true that the holder can't be null here but
scheglov
2016/11/09 03:11:35
Yes, I think so.
We create ElementHolder only when
| |
205 _walk(new ElementWalker.forExecutable(element, _enclosingUnit), () { | 229 _walk(new ElementWalker.forExecutable(element, _enclosingUnit), () { |
206 super.visitFunctionExpression(node); | 230 super.visitFunctionExpression(node); |
207 }); | 231 }); |
208 return null; | 232 return null; |
209 } else { | 233 } else { |
210 return super.visitFunctionExpression(node); | 234 return super.visitFunctionExpression(node); |
211 } | 235 } |
212 } | 236 } |
213 | 237 |
214 @override | 238 @override |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
454 * uses [ElementWalker.validate] to verify that all expected elements have | 478 * uses [ElementWalker.validate] to verify that all expected elements have |
455 * been matched. | 479 * been matched. |
456 */ | 480 */ |
457 void _walk(ElementWalker walker, void callback()) { | 481 void _walk(ElementWalker walker, void callback()) { |
458 ElementWalker outerWalker = _walker; | 482 ElementWalker outerWalker = _walker; |
459 _walker = walker; | 483 _walker = walker; |
460 callback(); | 484 callback(); |
461 walker.validate(); | 485 walker.validate(); |
462 _walker = outerWalker; | 486 _walker = outerWalker; |
463 } | 487 } |
488 | |
489 static bool _isBodyToCreateElementsFor(FunctionBody node) { | |
490 AstNode parent = node.parent; | |
491 return parent is ConstructorDeclaration || | |
492 parent is MethodDeclaration || | |
493 parent.parent is FunctionDeclaration && | |
494 parent.parent.parent is CompilationUnit; | |
495 } | |
464 } | 496 } |
465 | 497 |
466 /** | 498 /** |
467 * Keeps track of the set of non-synthetic child elements of an element, | 499 * Keeps track of the set of non-synthetic child elements of an element, |
468 * yielding them one at a time in response to "get" method calls. | 500 * yielding them one at a time in response to "get" method calls. |
469 */ | 501 */ |
470 class ElementWalker { | 502 class ElementWalker { |
471 /** | 503 /** |
472 * The element whose child elements are being walked. | 504 * The element whose child elements are being walked. |
473 */ | 505 */ |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
562 ElementWalker._forExecutable(ExecutableElement element, | 594 ElementWalker._forExecutable(ExecutableElement element, |
563 CompilationUnitElement compilationUnit, ElementHolder elementHolder) | 595 CompilationUnitElement compilationUnit, ElementHolder elementHolder) |
564 : element = element, | 596 : element = element, |
565 elementBuilder = | 597 elementBuilder = |
566 new LocalElementBuilder(elementHolder, compilationUnit), | 598 new LocalElementBuilder(elementHolder, compilationUnit), |
567 _elementHolder = elementHolder, | 599 _elementHolder = elementHolder, |
568 _functions = element.functions, | 600 _functions = element.functions, |
569 _parameters = element.parameters, | 601 _parameters = element.parameters, |
570 _typeParameters = element.typeParameters; | 602 _typeParameters = element.typeParameters; |
571 | 603 |
604 void consumeLocalElements() { | |
605 _functionIndex = _functions.length; | |
606 } | |
607 | |
572 /** | 608 /** |
573 * Returns the next non-synthetic child of [element] which is an accessor; | 609 * Returns the next non-synthetic child of [element] which is an accessor; |
574 * throws an [IndexError] if there are no more. | 610 * throws an [IndexError] if there are no more. |
575 */ | 611 */ |
576 PropertyAccessorElement getAccessor() => _accessors[_accessorIndex++]; | 612 PropertyAccessorElement getAccessor() => _accessors[_accessorIndex++]; |
577 | 613 |
578 /** | 614 /** |
579 * Returns the next non-synthetic child of [element] which is a class; throws | 615 * Returns the next non-synthetic child of [element] which is a class; throws |
580 * an [IndexError] if there are no more. | 616 * an [IndexError] if there are no more. |
581 */ | 617 */ |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
642 check(_classes, _classIndex); | 678 check(_classes, _classIndex); |
643 check(_constructors, _constructorIndex); | 679 check(_constructors, _constructorIndex); |
644 check(_enums, _enumIndex); | 680 check(_enums, _enumIndex); |
645 check(_functions, _functionIndex); | 681 check(_functions, _functionIndex); |
646 check(_parameters, _parameterIndex); | 682 check(_parameters, _parameterIndex); |
647 check(_typedefs, _typedefIndex); | 683 check(_typedefs, _typedefIndex); |
648 check(_typeParameters, _typeParameterIndex); | 684 check(_typeParameters, _typeParameterIndex); |
649 check(_variables, _variableIndex); | 685 check(_variables, _variableIndex); |
650 Element element = this.element; | 686 Element element = this.element; |
651 if (element is ExecutableElementImpl) { | 687 if (element is ExecutableElementImpl) { |
688 element.functions = _elementHolder.functions; | |
652 element.labels = _elementHolder.labels; | 689 element.labels = _elementHolder.labels; |
653 element.localVariables = _elementHolder.localVariables; | 690 element.localVariables = _elementHolder.localVariables; |
654 } | 691 } |
655 } | 692 } |
656 | 693 |
657 static bool _isNotSynthetic(Element e) => !e.isSynthetic; | 694 static bool _isNotSynthetic(Element e) => !e.isSynthetic; |
658 } | 695 } |
659 | 696 |
660 class _ElementMismatchException extends AnalysisException { | 697 class _ElementMismatchException extends AnalysisException { |
661 /** | 698 /** |
662 * Creates an exception to refer to the given [compilationUnit], [element], | 699 * Creates an exception to refer to the given [compilationUnit], [element], |
663 * and [cause]. | 700 * and [cause]. |
664 */ | 701 */ |
665 _ElementMismatchException( | 702 _ElementMismatchException( |
666 CompilationUnitElement compilationUnit, Element element, | 703 CompilationUnitElement compilationUnit, Element element, |
667 [CaughtException cause = null]) | 704 [CaughtException cause = null]) |
668 : super('Element mismatch in $compilationUnit at $element', cause); | 705 : super('Element mismatch in $compilationUnit at $element', cause); |
669 } | 706 } |
OLD | NEW |