Chromium Code Reviews| 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 |