| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 engine.incremental_resolver; | 5 library engine.incremental_resolver; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'ast.dart'; | 9 import 'ast.dart'; |
| 10 import 'element.dart'; | 10 import 'element.dart'; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 _gatherElements(element); | 83 _gatherElements(element); |
| 84 try { | 84 try { |
| 85 node.accept(this); | 85 node.accept(this); |
| 86 } on _DeclarationMismatchException catch (exception) { | 86 } on _DeclarationMismatchException catch (exception) { |
| 87 return false; | 87 return false; |
| 88 } | 88 } |
| 89 return _unmatchedElements.isEmpty; | 89 return _unmatchedElements.isEmpty; |
| 90 } | 90 } |
| 91 | 91 |
| 92 @override | 92 @override |
| 93 visitCatchClause(CatchClause node) { | 93 visitBlockFunctionBody(BlockFunctionBody node) { |
| 94 SimpleIdentifier exceptionParameter = node.exceptionParameter; | 94 // ignore bodies |
| 95 if (exceptionParameter != null) { | |
| 96 List<LocalVariableElement> localVariables = | |
| 97 _enclosingExecutable.localVariables; | |
| 98 LocalVariableElement exceptionElement = | |
| 99 _findIdentifier(localVariables, exceptionParameter); | |
| 100 _processElement(exceptionElement); | |
| 101 SimpleIdentifier stackTraceParameter = node.stackTraceParameter; | |
| 102 if (stackTraceParameter != null) { | |
| 103 LocalVariableElement stackTraceElement = | |
| 104 _findIdentifier(localVariables, stackTraceParameter); | |
| 105 _processElement(stackTraceElement); | |
| 106 } | |
| 107 } | |
| 108 super.visitCatchClause(node); | |
| 109 } | 95 } |
| 110 | 96 |
| 111 @override | 97 @override |
| 112 visitClassDeclaration(ClassDeclaration node) { | 98 visitClassDeclaration(ClassDeclaration node) { |
| 113 String name = node.name.name; | 99 String name = node.name.name; |
| 114 ClassElement clazz = _findElement(_enclosingUnit.types, name); | 100 ClassElement clazz = _findElement(_enclosingUnit.types, name); |
| 115 _enclosingClass = clazz; | 101 _enclosingClass = clazz; |
| 116 _processElement(clazz); | 102 _processElement(clazz); |
| 117 // check for missing clauses | 103 // check for missing clauses |
| 118 if (node.extendsClause == null) { | 104 if (node.extendsClause == null) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 _enclosingClass.getNamedConstructor(constructorName.name); | 154 _enclosingClass.getNamedConstructor(constructorName.name); |
| 169 } | 155 } |
| 170 _processElement(_enclosingExecutable); | 156 _processElement(_enclosingExecutable); |
| 171 super.visitConstructorDeclaration(node); | 157 super.visitConstructorDeclaration(node); |
| 172 } finally { | 158 } finally { |
| 173 _enclosingExecutable = outerExecutable; | 159 _enclosingExecutable = outerExecutable; |
| 174 } | 160 } |
| 175 } | 161 } |
| 176 | 162 |
| 177 @override | 163 @override |
| 178 visitDeclaredIdentifier(DeclaredIdentifier node) { | |
| 179 SimpleIdentifier variableName = node.identifier; | |
| 180 LocalVariableElement element = | |
| 181 _findIdentifier(_enclosingExecutable.localVariables, variableName); | |
| 182 _processElement(element); | |
| 183 super.visitDeclaredIdentifier(node); | |
| 184 } | |
| 185 | |
| 186 @override | |
| 187 visitDefaultFormalParameter(DefaultFormalParameter node) { | 164 visitDefaultFormalParameter(DefaultFormalParameter node) { |
| 188 SimpleIdentifier parameterName = node.parameter.identifier; | 165 SimpleIdentifier parameterName = node.parameter.identifier; |
| 189 ParameterElement element = _getElementForParameter(node, parameterName); | 166 ParameterElement element = _getElementForParameter(node, parameterName); |
| 190 Expression defaultValue = node.defaultValue; | 167 Expression defaultValue = node.defaultValue; |
| 191 if (defaultValue != null) { | 168 if (defaultValue != null) { |
| 192 ExecutableElement outerExecutable = _enclosingExecutable; | 169 ExecutableElement outerExecutable = _enclosingExecutable; |
| 193 try { | 170 try { |
| 194 if (element == null) { | 171 if (element == null) { |
| 195 // TODO(brianwilkerson) Report this internal error. | 172 // TODO(brianwilkerson) Report this internal error. |
| 196 } else { | 173 } else { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 LibraryElement library = _enclosingUnit.library; | 209 LibraryElement library = _enclosingUnit.library; |
| 233 ExportElement exportElement = _findExport( | 210 ExportElement exportElement = _findExport( |
| 234 library.exports, | 211 library.exports, |
| 235 _enclosingUnit.context.sourceFactory.resolveUri(_enclosingUnit.source,
uri)); | 212 _enclosingUnit.context.sourceFactory.resolveUri(_enclosingUnit.source,
uri)); |
| 236 _processElement(exportElement); | 213 _processElement(exportElement); |
| 237 } | 214 } |
| 238 super.visitExportDirective(node); | 215 super.visitExportDirective(node); |
| 239 } | 216 } |
| 240 | 217 |
| 241 @override | 218 @override |
| 219 visitExpressionFunctionBody(ExpressionFunctionBody node) { |
| 220 // ignore bodies |
| 221 } |
| 222 |
| 223 @override |
| 242 visitExtendsClause(ExtendsClause node) { | 224 visitExtendsClause(ExtendsClause node) { |
| 243 _assertSameType(node.superclass, _enclosingClass.supertype); | 225 _assertSameType(node.superclass, _enclosingClass.supertype); |
| 244 } | 226 } |
| 245 | 227 |
| 246 @override | 228 @override |
| 247 visitFieldFormalParameter(FieldFormalParameter node) { | 229 visitFieldFormalParameter(FieldFormalParameter node) { |
| 248 if (node.parent is! DefaultFormalParameter) { | 230 if (node.parent is! DefaultFormalParameter) { |
| 249 SimpleIdentifier parameterName = node.identifier; | 231 SimpleIdentifier parameterName = node.identifier; |
| 250 ParameterElement element = _getElementForParameter(node, parameterName); | 232 ParameterElement element = _getElementForParameter(node, parameterName); |
| 251 ParameterElement outerParameter = _enclosingParameter; | 233 ParameterElement outerParameter = _enclosingParameter; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 _enclosingExecutable = accessor; | 266 _enclosingExecutable = accessor; |
| 285 } | 267 } |
| 286 _processElement(_enclosingExecutable); | 268 _processElement(_enclosingExecutable); |
| 287 super.visitFunctionDeclaration(node); | 269 super.visitFunctionDeclaration(node); |
| 288 } finally { | 270 } finally { |
| 289 _enclosingExecutable = outerExecutable; | 271 _enclosingExecutable = outerExecutable; |
| 290 } | 272 } |
| 291 } | 273 } |
| 292 | 274 |
| 293 @override | 275 @override |
| 294 visitFunctionExpression(FunctionExpression node) { | |
| 295 if (node.parent is! FunctionDeclaration) { | |
| 296 FunctionElement element = | |
| 297 _findAtOffset(_enclosingExecutable.functions, node.beginToken.offset); | |
| 298 _processElement(element); | |
| 299 } | |
| 300 ExecutableElement outerExecutable = _enclosingExecutable; | |
| 301 try { | |
| 302 _enclosingExecutable = node.element; | |
| 303 _processElement(_enclosingExecutable); | |
| 304 super.visitFunctionExpression(node); | |
| 305 } finally { | |
| 306 _enclosingExecutable = outerExecutable; | |
| 307 } | |
| 308 } | |
| 309 | |
| 310 @override | |
| 311 visitFunctionTypeAlias(FunctionTypeAlias node) { | 276 visitFunctionTypeAlias(FunctionTypeAlias node) { |
| 312 FunctionTypeAliasElement outerAlias = _enclosingAlias; | 277 FunctionTypeAliasElement outerAlias = _enclosingAlias; |
| 313 try { | 278 try { |
| 314 SimpleIdentifier aliasName = node.name; | 279 SimpleIdentifier aliasName = node.name; |
| 315 _enclosingAlias = | 280 _enclosingAlias = |
| 316 _findIdentifier(_enclosingUnit.functionTypeAliases, aliasName); | 281 _findIdentifier(_enclosingUnit.functionTypeAliases, aliasName); |
| 317 _processElement(_enclosingAlias); | 282 _processElement(_enclosingAlias); |
| 318 super.visitFunctionTypeAlias(node); | 283 super.visitFunctionTypeAlias(node); |
| 319 } finally { | 284 } finally { |
| 320 _enclosingAlias = outerAlias; | 285 _enclosingAlias = outerAlias; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 ImportElement importElement = _findImport( | 319 ImportElement importElement = _findImport( |
| 355 library.imports, | 320 library.imports, |
| 356 _enclosingUnit.context.sourceFactory.resolveUri(_enclosingUnit.source,
uri), | 321 _enclosingUnit.context.sourceFactory.resolveUri(_enclosingUnit.source,
uri), |
| 357 node.prefix); | 322 node.prefix); |
| 358 _processElement(importElement); | 323 _processElement(importElement); |
| 359 } | 324 } |
| 360 super.visitImportDirective(node); | 325 super.visitImportDirective(node); |
| 361 } | 326 } |
| 362 | 327 |
| 363 @override | 328 @override |
| 364 visitLabeledStatement(LabeledStatement node) { | |
| 365 for (Label label in node.labels) { | |
| 366 SimpleIdentifier labelName = label.label; | |
| 367 LabelElement element = | |
| 368 _findIdentifier(_enclosingExecutable.labels, labelName); | |
| 369 _processElement(element); | |
| 370 } | |
| 371 super.visitLabeledStatement(node); | |
| 372 } | |
| 373 | |
| 374 @override | |
| 375 visitMethodDeclaration(MethodDeclaration node) { | 329 visitMethodDeclaration(MethodDeclaration node) { |
| 376 ExecutableElement outerExecutable = _enclosingExecutable; | 330 ExecutableElement outerExecutable = _enclosingExecutable; |
| 377 try { | 331 try { |
| 378 Token property = node.propertyKeyword; | 332 Token property = node.propertyKeyword; |
| 379 SimpleIdentifier methodName = node.name; | 333 SimpleIdentifier methodName = node.name; |
| 380 String nameOfMethod = methodName.name; | 334 String nameOfMethod = methodName.name; |
| 381 if (nameOfMethod == TokenType.MINUS.lexeme && | 335 if (nameOfMethod == TokenType.MINUS.lexeme && |
| 382 node.parameters.parameters.length == 0) { | 336 node.parameters.parameters.length == 0) { |
| 383 nameOfMethod = "unary-"; | 337 nameOfMethod = "unary-"; |
| 384 } | 338 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 super.visitSimpleFormalParameter(node); | 383 super.visitSimpleFormalParameter(node); |
| 430 } finally { | 384 } finally { |
| 431 _enclosingParameter = outerParameter; | 385 _enclosingParameter = outerParameter; |
| 432 } | 386 } |
| 433 } else { | 387 } else { |
| 434 } | 388 } |
| 435 super.visitSimpleFormalParameter(node); | 389 super.visitSimpleFormalParameter(node); |
| 436 } | 390 } |
| 437 | 391 |
| 438 @override | 392 @override |
| 439 visitSwitchCase(SwitchCase node) { | |
| 440 for (Label label in node.labels) { | |
| 441 SimpleIdentifier labelName = label.label; | |
| 442 LabelElement element = | |
| 443 _findIdentifier(_enclosingExecutable.labels, labelName); | |
| 444 _processElement(element); | |
| 445 } | |
| 446 super.visitSwitchCase(node); | |
| 447 } | |
| 448 | |
| 449 @override | |
| 450 visitSwitchDefault(SwitchDefault node) { | |
| 451 for (Label label in node.labels) { | |
| 452 SimpleIdentifier labelName = label.label; | |
| 453 LabelElement element = | |
| 454 _findIdentifier(_enclosingExecutable.labels, labelName); | |
| 455 _processElement(element); | |
| 456 } | |
| 457 super.visitSwitchDefault(node); | |
| 458 } | |
| 459 | |
| 460 @override | |
| 461 visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { | 393 visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { |
| 462 _inTopLevelVariableDeclaration = true; | 394 _inTopLevelVariableDeclaration = true; |
| 463 try { | 395 try { |
| 464 super.visitTopLevelVariableDeclaration(node); | 396 super.visitTopLevelVariableDeclaration(node); |
| 465 } finally { | 397 } finally { |
| 466 _inTopLevelVariableDeclaration = false; | 398 _inTopLevelVariableDeclaration = false; |
| 467 } | 399 } |
| 468 } | 400 } |
| 469 | 401 |
| 470 @override | 402 @override |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 591 } else if (parent is ParameterElement) { | 523 } else if (parent is ParameterElement) { |
| 592 if (_enclosingParameter == null) { | 524 if (_enclosingParameter == null) { |
| 593 _enclosingParameter = parent as ParameterElement; | 525 _enclosingParameter = parent as ParameterElement; |
| 594 } | 526 } |
| 595 } | 527 } |
| 596 parent = parent.enclosingElement; | 528 parent = parent.enclosingElement; |
| 597 } | 529 } |
| 598 } | 530 } |
| 599 | 531 |
| 600 /** | 532 /** |
| 601 * Return the element in the given array of elements that was created for the
declaration at the | |
| 602 * given offset. This method should only be used when there is no name | |
| 603 * | |
| 604 * @param elements the elements of the appropriate kind that exist in the curr
ent context | |
| 605 * @param offset the offset of the name of the element to be returned | |
| 606 * @return the element at the given offset | |
| 607 */ | |
| 608 Element _findAtOffset(List<Element> elements, int offset) => | |
| 609 _findWithNameAndOffset(elements, "", offset); | |
| 610 | |
| 611 /** | |
| 612 * Return the [Element] in [elements] with the given [name]. | 533 * Return the [Element] in [elements] with the given [name]. |
| 613 */ | 534 */ |
| 614 Element _findElement(List<Element> elements, String name) { | 535 Element _findElement(List<Element> elements, String name) { |
| 615 for (Element element in elements) { | 536 for (Element element in elements) { |
| 616 if (element.displayName == name) { | 537 if (element.displayName == name) { |
| 617 return element; | 538 return element; |
| 618 } | 539 } |
| 619 } | 540 } |
| 620 return null; | 541 return null; |
| 621 } | 542 } |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 829 * | 750 * |
| 830 * [node] - the root of the AST structure to be resolved. | 751 * [node] - the root of the AST structure to be resolved. |
| 831 */ | 752 */ |
| 832 void resolve(AstNode node) { | 753 void resolve(AstNode node) { |
| 833 AstNode rootNode = _findResolutionRoot(node); | 754 AstNode rootNode = _findResolutionRoot(node); |
| 834 Scope scope = ScopeBuilder.scopeFor(rootNode, _errorListener); | 755 Scope scope = ScopeBuilder.scopeFor(rootNode, _errorListener); |
| 835 if (_elementModelChanged(rootNode.parent)) { | 756 if (_elementModelChanged(rootNode.parent)) { |
| 836 throw new AnalysisException("Cannot resolve node: element model changed"); | 757 throw new AnalysisException("Cannot resolve node: element model changed"); |
| 837 } | 758 } |
| 838 _definingUnit.accept( | 759 _definingUnit.accept( |
| 839 new _ElementNameOffsetUpdater(_updateOffset, _updateNewLength - _updateO
ldLength)); | 760 new _ElementNameOffsetUpdater( |
| 761 _updateOffset, |
| 762 _updateNewLength - _updateOldLength)); |
| 840 _resolveTypes(node, scope); | 763 _resolveTypes(node, scope); |
| 841 _resolveVariables(node, scope); | 764 _resolveVariables(node, scope); |
| 842 _resolveReferences(node, scope); | 765 _resolveReferences(node, scope); |
| 843 } | 766 } |
| 844 | 767 |
| 845 /** | 768 /** |
| 846 * Return `true` if the given node can be resolved independently of any other | 769 * Return `true` if the given node can be resolved independently of any other |
| 847 * nodes. | 770 * nodes. |
| 848 * | 771 * |
| 849 * *Note*: This method needs to be kept in sync with | 772 * *Note*: This method needs to be kept in sync with |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1075 | 998 |
| 1076 /** | 999 /** |
| 1077 * Instances of the class [_DeclarationMismatchException] represent an exception | 1000 * Instances of the class [_DeclarationMismatchException] represent an exception |
| 1078 * that is thrown when the element model defined by a given AST structure does | 1001 * that is thrown when the element model defined by a given AST structure does |
| 1079 * not match an existing element model. | 1002 * not match an existing element model. |
| 1080 */ | 1003 */ |
| 1081 class _DeclarationMismatchException { | 1004 class _DeclarationMismatchException { |
| 1082 } | 1005 } |
| 1083 | 1006 |
| 1084 | 1007 |
| 1008 class _ElementNameOffsetUpdater extends GeneralizingElementVisitor { |
| 1009 final int updateOffset; |
| 1010 final int updateDelta; |
| 1011 |
| 1012 _ElementNameOffsetUpdater(this.updateOffset, this.updateDelta); |
| 1013 |
| 1014 @override |
| 1015 visitElement(Element element) { |
| 1016 int nameOffset = element.nameOffset; |
| 1017 if (nameOffset >= updateOffset) { |
| 1018 (element as ElementImpl).nameOffset = nameOffset + updateDelta; |
| 1019 } |
| 1020 super.visitElement(element); |
| 1021 } |
| 1022 } |
| 1023 |
| 1024 |
| 1085 class _ElementsGatherer extends GeneralizingElementVisitor { | 1025 class _ElementsGatherer extends GeneralizingElementVisitor { |
| 1086 final DeclarationMatcher matcher; | 1026 final DeclarationMatcher matcher; |
| 1087 | 1027 |
| 1088 _ElementsGatherer(this.matcher); | 1028 _ElementsGatherer(this.matcher); |
| 1089 | 1029 |
| 1090 @override | 1030 @override |
| 1091 visitElement(Element element) { | 1031 visitElement(Element element) { |
| 1092 _addElement(element); | 1032 _addElement(element); |
| 1093 super.visitElement(element); | 1033 super.visitElement(element); |
| 1094 } | 1034 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1118 } | 1058 } |
| 1119 } | 1059 } |
| 1120 | 1060 |
| 1121 void _addElement(Element element) { | 1061 void _addElement(Element element) { |
| 1122 if (element != null) { | 1062 if (element != null) { |
| 1123 matcher._allElements.add(element); | 1063 matcher._allElements.add(element); |
| 1124 matcher._unmatchedElements.add(element); | 1064 matcher._unmatchedElements.add(element); |
| 1125 } | 1065 } |
| 1126 } | 1066 } |
| 1127 } | 1067 } |
| 1128 | |
| 1129 | |
| 1130 class _ElementNameOffsetUpdater extends GeneralizingElementVisitor { | |
| 1131 final int updateOffset; | |
| 1132 final int updateDelta; | |
| 1133 | |
| 1134 _ElementNameOffsetUpdater(this.updateOffset, this.updateDelta); | |
| 1135 | |
| 1136 @override | |
| 1137 visitElement(Element element) { | |
| 1138 int nameOffset = element.nameOffset; | |
| 1139 if (nameOffset >= updateOffset) { | |
| 1140 (element as ElementImpl).nameOffset = nameOffset + updateDelta; | |
| 1141 } | |
| 1142 super.visitElement(element); | |
| 1143 } | |
| 1144 } | |
| OLD | NEW |