| 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 import 'dart:math' as math; | 8 import 'dart:math' as math; |
| 9 | 9 |
| 10 import 'package:analyzer/src/generated/error_verifier.dart'; | 10 import 'package:analyzer/src/generated/error_verifier.dart'; |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 visitBlockFunctionBody(BlockFunctionBody node) { | 98 visitBlockFunctionBody(BlockFunctionBody node) { |
| 99 // ignore bodies | 99 // ignore bodies |
| 100 } | 100 } |
| 101 | 101 |
| 102 @override | 102 @override |
| 103 visitClassDeclaration(ClassDeclaration node) { | 103 visitClassDeclaration(ClassDeclaration node) { |
| 104 String name = node.name.name; | 104 String name = node.name.name; |
| 105 ClassElement element = _findElement(_enclosingUnit.types, name); | 105 ClassElement element = _findElement(_enclosingUnit.types, name); |
| 106 _enclosingClass = element; | 106 _enclosingClass = element; |
| 107 _processElement(element); | 107 _processElement(element); |
| 108 _assertSameTypeParameters(node.typeParameters, element.typeParameters); |
| 108 // check for missing clauses | 109 // check for missing clauses |
| 109 if (node.extendsClause == null) { | 110 if (node.extendsClause == null) { |
| 110 _assertTrue(element.supertype.name == 'Object'); | 111 _assertTrue(element.supertype.name == 'Object'); |
| 111 } | 112 } |
| 112 if (node.implementsClause == null) { | 113 if (node.implementsClause == null) { |
| 113 _assertTrue(element.interfaces.isEmpty); | 114 _assertTrue(element.interfaces.isEmpty); |
| 114 } | 115 } |
| 115 if (node.withClause == null) { | 116 if (node.withClause == null) { |
| 116 _assertTrue(element.mixins.isEmpty); | 117 _assertTrue(element.mixins.isEmpty); |
| 117 } | 118 } |
| 118 // process clauses and members | 119 // process clauses and members |
| 119 _hasConstructor = false; | 120 _hasConstructor = false; |
| 120 super.visitClassDeclaration(node); | 121 super.visitClassDeclaration(node); |
| 121 // process default constructor | 122 // process default constructor |
| 122 if (!_hasConstructor) { | 123 if (!_hasConstructor) { |
| 123 ConstructorElement constructor = element.unnamedConstructor; | 124 ConstructorElement constructor = element.unnamedConstructor; |
| 124 _processElement(constructor); | 125 _processElement(constructor); |
| 125 if (!constructor.isSynthetic) { | 126 if (!constructor.isSynthetic) { |
| 126 _assertEquals(constructor.parameters.length, 0); | 127 _assertEquals(constructor.parameters.length, 0); |
| 127 } | 128 } |
| 128 } | 129 } |
| 129 } | 130 } |
| 130 | 131 |
| 131 @override | 132 @override |
| 132 visitClassTypeAlias(ClassTypeAlias node) { | 133 visitClassTypeAlias(ClassTypeAlias node) { |
| 133 String name = node.name.name; | 134 String name = node.name.name; |
| 134 ClassElement element = _findElement(_enclosingUnit.types, name); | 135 ClassElement element = _findElement(_enclosingUnit.types, name); |
| 135 _enclosingClass = element; | 136 _enclosingClass = element; |
| 136 _processElement(element); | 137 _processElement(element); |
| 138 _assertSameTypeParameters(node.typeParameters, element.typeParameters); |
| 137 _processElement(element.unnamedConstructor); | 139 _processElement(element.unnamedConstructor); |
| 138 super.visitClassTypeAlias(node); | 140 super.visitClassTypeAlias(node); |
| 139 } | 141 } |
| 140 | 142 |
| 141 @override | 143 @override |
| 142 visitCompilationUnit(CompilationUnit node) { | 144 visitCompilationUnit(CompilationUnit node) { |
| 143 _processElement(_enclosingUnit); | 145 _processElement(_enclosingUnit); |
| 144 super.visitCompilationUnit(node); | 146 super.visitCompilationUnit(node); |
| 145 } | 147 } |
| 146 | 148 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 node.functionExpression.element = element; | 227 node.functionExpression.element = element; |
| 226 _assertFalse(element.isSynthetic); | 228 _assertFalse(element.isSynthetic); |
| 227 _assertSameType(node.returnType, element.returnType); | 229 _assertSameType(node.returnType, element.returnType); |
| 228 _assertCompatibleParameters( | 230 _assertCompatibleParameters( |
| 229 node.functionExpression.parameters, | 231 node.functionExpression.parameters, |
| 230 element.parameters); | 232 element.parameters); |
| 231 } | 233 } |
| 232 | 234 |
| 233 @override | 235 @override |
| 234 visitFunctionTypeAlias(FunctionTypeAlias node) { | 236 visitFunctionTypeAlias(FunctionTypeAlias node) { |
| 235 FunctionTypeAliasElement outerAlias = _enclosingAlias; | 237 String name = node.name.name; |
| 236 try { | 238 FunctionTypeAliasElement element = |
| 237 SimpleIdentifier aliasName = node.name; | 239 _findElement(_enclosingUnit.functionTypeAliases, name); |
| 238 _enclosingAlias = | 240 _processElement(element); |
| 239 _findIdentifier(_enclosingUnit.functionTypeAliases, aliasName); | 241 _assertSameTypeParameters(node.typeParameters, element.typeParameters); |
| 240 _processElement(_enclosingAlias); | 242 _assertSameType(node.returnType, element.returnType); |
| 241 super.visitFunctionTypeAlias(node); | 243 _assertCompatibleParameters(node.parameters, element.parameters); |
| 242 } finally { | |
| 243 _enclosingAlias = outerAlias; | |
| 244 } | |
| 245 } | 244 } |
| 246 | 245 |
| 247 @override | 246 @override |
| 248 visitImplementsClause(ImplementsClause node) { | 247 visitImplementsClause(ImplementsClause node) { |
| 249 List<TypeName> nodes = node.interfaces; | 248 List<TypeName> nodes = node.interfaces; |
| 250 List<InterfaceType> types = _enclosingClass.interfaces; | 249 List<InterfaceType> types = _enclosingClass.interfaces; |
| 251 _assertSameTypes(nodes, types); | 250 _assertSameTypes(nodes, types); |
| 252 } | 251 } |
| 253 | 252 |
| 254 @override | 253 @override |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { | 310 visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { |
| 312 _inTopLevelVariableDeclaration = true; | 311 _inTopLevelVariableDeclaration = true; |
| 313 try { | 312 try { |
| 314 super.visitTopLevelVariableDeclaration(node); | 313 super.visitTopLevelVariableDeclaration(node); |
| 315 } finally { | 314 } finally { |
| 316 _inTopLevelVariableDeclaration = false; | 315 _inTopLevelVariableDeclaration = false; |
| 317 } | 316 } |
| 318 } | 317 } |
| 319 | 318 |
| 320 @override | 319 @override |
| 321 visitTypeParameter(TypeParameter node) { | |
| 322 String name = node.name.name; | |
| 323 TypeParameterElement element = null; | |
| 324 if (_enclosingClass != null) { | |
| 325 element = _findElement(_enclosingClass.typeParameters, name); | |
| 326 } else if (_enclosingAlias != null) { | |
| 327 element = _findElement(_enclosingAlias.typeParameters, name); | |
| 328 } | |
| 329 _processElement(element); | |
| 330 _assertSameType(node.bound, element.bound); | |
| 331 } | |
| 332 | |
| 333 @override | |
| 334 visitVariableDeclaration(VariableDeclaration node) { | 320 visitVariableDeclaration(VariableDeclaration node) { |
| 335 // prepare variable | 321 // prepare variable |
| 336 String name = node.name.name; | 322 String name = node.name.name; |
| 337 PropertyInducingElement element; | 323 PropertyInducingElement element; |
| 338 if (_inTopLevelVariableDeclaration) { | 324 if (_inTopLevelVariableDeclaration) { |
| 339 element = _findElement(_enclosingUnit.topLevelVariables, name); | 325 element = _findElement(_enclosingUnit.topLevelVariables, name); |
| 340 } else { | 326 } else { |
| 341 element = _findElement(_enclosingClass.fields, name); | 327 element = _findElement(_enclosingClass.fields, name); |
| 342 } | 328 } |
| 343 // verify | 329 // verify |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 _assertEquals(nodeName, 'void'); | 465 _assertEquals(nodeName, 'void'); |
| 480 } else if (type.isDynamic) { | 466 } else if (type.isDynamic) { |
| 481 _assertEquals(nodeName, 'dynamic'); | 467 _assertEquals(nodeName, 'dynamic'); |
| 482 } else { | 468 } else { |
| 483 // TODO(scheglov) support other types | 469 // TODO(scheglov) support other types |
| 484 // print('node: $node type: $type type.type: ${type.runtimeType}'); | 470 // print('node: $node type: $type type.type: ${type.runtimeType}'); |
| 485 _assertTrue(false); | 471 _assertTrue(false); |
| 486 } | 472 } |
| 487 } | 473 } |
| 488 | 474 |
| 475 void _assertSameTypeParameter(TypeParameter node, |
| 476 TypeParameterElement element) { |
| 477 _assertSameType(node.bound, element.bound); |
| 478 } |
| 479 |
| 480 void _assertSameTypeParameters(TypeParameterList nodesList, |
| 481 List<TypeParameterElement> elements) { |
| 482 if (nodesList == null) { |
| 483 return _assertEquals(elements.length, 0); |
| 484 } |
| 485 List<TypeParameter> nodes = nodesList.typeParameters; |
| 486 int length = nodes.length; |
| 487 _assertEquals(length, elements.length); |
| 488 for (int i = 0; i < length; i++) { |
| 489 _assertSameTypeParameter(nodes[i], elements[i]); |
| 490 } |
| 491 } |
| 492 |
| 489 void _assertSameTypes(List<TypeName> nodes, List<DartType> types) { | 493 void _assertSameTypes(List<TypeName> nodes, List<DartType> types) { |
| 490 int length = nodes.length; | 494 int length = nodes.length; |
| 491 _assertEquals(length, types.length); | 495 _assertEquals(length, types.length); |
| 492 for (int i = 0; i < length; i++) { | 496 for (int i = 0; i < length; i++) { |
| 493 _assertSameType(nodes[i], types[i]); | 497 _assertSameType(nodes[i], types[i]); |
| 494 } | 498 } |
| 495 } | 499 } |
| 496 | 500 |
| 497 void _assertTrue(bool condition) { | 501 void _assertTrue(bool condition) { |
| 498 if (!condition) { | 502 if (!condition) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 521 } | 525 } |
| 522 } else if (parent is ParameterElement) { | 526 } else if (parent is ParameterElement) { |
| 523 if (_enclosingParameter == null) { | 527 if (_enclosingParameter == null) { |
| 524 _enclosingParameter = parent as ParameterElement; | 528 _enclosingParameter = parent as ParameterElement; |
| 525 } | 529 } |
| 526 } | 530 } |
| 527 parent = parent.enclosingElement; | 531 parent = parent.enclosingElement; |
| 528 } | 532 } |
| 529 } | 533 } |
| 530 | 534 |
| 531 /** | |
| 532 * Return the [Element] in [elements] with the given [name]. | |
| 533 */ | |
| 534 Element _findElement(List<Element> elements, String name) { | |
| 535 for (Element element in elements) { | |
| 536 if (element.name == name) { | |
| 537 return element; | |
| 538 } | |
| 539 } | |
| 540 return null; | |
| 541 } | |
| 542 | |
| 543 /** | |
| 544 * Return the element in the given array of elements that was created for the
declaration with the | |
| 545 * given name. | |
| 546 * | |
| 547 * @param elements the elements of the appropriate kind that exist in the curr
ent context | |
| 548 * @param identifier the name node in the declaration of the element to be ret
urned | |
| 549 * @return the element created for the declaration with the given name | |
| 550 */ | |
| 551 Element _findIdentifier(List<Element> elements, | |
| 552 SimpleIdentifier identifier) => | |
| 553 _findWithNameAndOffset(elements, identifier.name, identifier.offset); | |
| 554 | |
| 555 /** | |
| 556 * Return the element in the given array of elements that was created for the
declaration with the | |
| 557 * given name at the given offset. | |
| 558 * | |
| 559 * @param elements the elements of the appropriate kind that exist in the curr
ent context | |
| 560 * @param name the name of the element to be returned | |
| 561 * @param offset the offset of the name of the element to be returned | |
| 562 * @return the element with the given name and offset | |
| 563 */ | |
| 564 Element _findWithNameAndOffset(List<Element> elements, String name, | |
| 565 int offset) { | |
| 566 for (Element element in elements) { | |
| 567 if (element.displayName == name && element.nameOffset == offset) { | |
| 568 return element; | |
| 569 } | |
| 570 } | |
| 571 return null; | |
| 572 } | |
| 573 | |
| 574 void _gatherElements(Element element) { | 535 void _gatherElements(Element element) { |
| 575 _ElementsGatherer gatherer = new _ElementsGatherer(this); | 536 _ElementsGatherer gatherer = new _ElementsGatherer(this); |
| 576 element.accept(gatherer); | 537 element.accept(gatherer); |
| 577 // TODO(scheglov) what if a change in a directive? | 538 // TODO(scheglov) what if a change in a directive? |
| 578 if (identical(element, _enclosingLibrary.definingCompilationUnit)) { | 539 if (identical(element, _enclosingLibrary.definingCompilationUnit)) { |
| 579 gatherer.addElements(_enclosingLibrary.imports); | 540 gatherer.addElements(_enclosingLibrary.imports); |
| 580 gatherer.addElements(_enclosingLibrary.exports); | 541 gatherer.addElements(_enclosingLibrary.exports); |
| 581 gatherer.addElements(_enclosingLibrary.parts); | 542 gatherer.addElements(_enclosingLibrary.parts); |
| 582 } | 543 } |
| 583 } | 544 } |
| 584 | 545 |
| 585 /** | |
| 586 * Return the value of the given string literal, or `null` if the string is no
t a constant | |
| 587 * string without any string interpolation. | |
| 588 * | |
| 589 * @param literal the string literal whose value is to be returned | |
| 590 * @return the value of the given string literal | |
| 591 */ | |
| 592 String _getStringValue(StringLiteral literal) { | |
| 593 if (literal is StringInterpolation) { | |
| 594 return null; | |
| 595 } | |
| 596 return literal.stringValue; | |
| 597 } | |
| 598 | |
| 599 void _processElement(Element element) { | 546 void _processElement(Element element) { |
| 600 _assertNotNull(element); | 547 _assertNotNull(element); |
| 601 if (!_allElements.contains(element)) { | 548 if (!_allElements.contains(element)) { |
| 602 throw new _DeclarationMismatchException(); | 549 throw new _DeclarationMismatchException(); |
| 603 } | 550 } |
| 604 _unmatchedElements.remove(element); | 551 _unmatchedElements.remove(element); |
| 605 } | 552 } |
| 606 | 553 |
| 607 /** | 554 /** |
| 555 * Return the [Element] in [elements] with the given [name]. |
| 556 */ |
| 557 static Element _findElement(List<Element> elements, String name) { |
| 558 for (Element element in elements) { |
| 559 if (element.name == name) { |
| 560 return element; |
| 561 } |
| 562 } |
| 563 return null; |
| 564 } |
| 565 |
| 566 /** |
| 608 * Return the [UriReferencedElement] from [elements] with the given [uri], or | 567 * Return the [UriReferencedElement] from [elements] with the given [uri], or |
| 609 * `null` if there is no such element. | 568 * `null` if there is no such element. |
| 610 */ | 569 */ |
| 611 static UriReferencedElement | 570 static UriReferencedElement |
| 612 _findUriReferencedElement(List<UriReferencedElement> elements, String uri)
{ | 571 _findUriReferencedElement(List<UriReferencedElement> elements, String uri)
{ |
| 613 for (UriReferencedElement element in elements) { | 572 for (UriReferencedElement element in elements) { |
| 614 if (element.uri == uri) { | 573 if (element.uri == uri) { |
| 615 return element; | 574 return element; |
| 616 } | 575 } |
| 617 } | 576 } |
| 618 return null; | 577 return null; |
| 619 } | 578 } |
| 579 |
| 580 /** |
| 581 * Return the value of [literal], or `null` if the string is not a constant |
| 582 * string without any string interpolation. |
| 583 */ |
| 584 static String _getStringValue(StringLiteral literal) { |
| 585 if (literal is StringInterpolation) { |
| 586 return null; |
| 587 } |
| 588 return literal.stringValue; |
| 589 } |
| 620 } | 590 } |
| 621 | 591 |
| 622 | 592 |
| 623 /** | 593 /** |
| 624 * Instances of the class [IncrementalResolver] resolve the smallest portion of | 594 * Instances of the class [IncrementalResolver] resolve the smallest portion of |
| 625 * an AST structure that we currently know how to resolve. | 595 * an AST structure that we currently know how to resolve. |
| 626 */ | 596 */ |
| 627 class IncrementalResolver { | 597 class IncrementalResolver { |
| 628 /** | 598 /** |
| 629 * The object used to access the types from the core library. | 599 * The object used to access the types from the core library. |
| (...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1317 _addElement(element); | 1287 _addElement(element); |
| 1318 super.visitElement(element); | 1288 super.visitElement(element); |
| 1319 } | 1289 } |
| 1320 | 1290 |
| 1321 @override | 1291 @override |
| 1322 visitExecutableElement(ExecutableElement element) { | 1292 visitExecutableElement(ExecutableElement element) { |
| 1323 _addElement(element); | 1293 _addElement(element); |
| 1324 } | 1294 } |
| 1325 | 1295 |
| 1326 @override | 1296 @override |
| 1297 visitParameterElement(ParameterElement element) { |
| 1298 } |
| 1299 |
| 1300 @override |
| 1327 visitPropertyAccessorElement(PropertyAccessorElement element) { | 1301 visitPropertyAccessorElement(PropertyAccessorElement element) { |
| 1328 if (!element.isSynthetic) { | 1302 if (!element.isSynthetic) { |
| 1329 _addElement(element); | 1303 _addElement(element); |
| 1330 } | 1304 } |
| 1331 // Don't visit children (such as synthetic setter parameters). | 1305 // Don't visit children (such as synthetic setter parameters). |
| 1332 } | 1306 } |
| 1333 | 1307 |
| 1334 @override | 1308 @override |
| 1335 visitPropertyInducingElement(PropertyInducingElement element) { | 1309 visitPropertyInducingElement(PropertyInducingElement element) { |
| 1336 if (!element.isSynthetic) { | 1310 if (!element.isSynthetic) { |
| 1337 _addElement(element); | 1311 _addElement(element); |
| 1338 } | 1312 } |
| 1339 // Don't visit children (such as property accessors). | 1313 // Don't visit children (such as property accessors). |
| 1340 } | 1314 } |
| 1341 | 1315 |
| 1316 @override |
| 1317 visitTypeParameterElement(TypeParameterElement element) { |
| 1318 } |
| 1319 |
| 1342 void _addElement(Element element) { | 1320 void _addElement(Element element) { |
| 1343 if (element != null) { | 1321 if (element != null) { |
| 1344 matcher._allElements.add(element); | 1322 matcher._allElements.add(element); |
| 1345 matcher._unmatchedElements.add(element); | 1323 matcher._unmatchedElements.add(element); |
| 1346 } | 1324 } |
| 1347 } | 1325 } |
| 1348 } | 1326 } |
| 1349 | 1327 |
| 1350 | 1328 |
| 1351 /** | 1329 /** |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1397 _elements[node] = node.staticElement; | 1375 _elements[node] = node.staticElement; |
| 1398 } | 1376 } |
| 1399 } | 1377 } |
| 1400 | 1378 |
| 1401 | 1379 |
| 1402 class _TokenPair { | 1380 class _TokenPair { |
| 1403 final Token oldToken; | 1381 final Token oldToken; |
| 1404 final Token newToken; | 1382 final Token newToken; |
| 1405 _TokenPair(this.oldToken, this.newToken); | 1383 _TokenPair(this.oldToken, this.newToken); |
| 1406 } | 1384 } |
| OLD | NEW |