| 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 /** | 5 /** |
| 6 * This library is capable of producing linked summaries from unlinked | 6 * This library is capable of producing linked summaries from unlinked |
| 7 * ones (or prelinked ones). It functions by building a miniature | 7 * ones (or prelinked ones). It functions by building a miniature |
| 8 * element model to represent the contents of the summaries, and then | 8 * element model to represent the contents of the summaries, and then |
| 9 * scanning the element model to gather linked information and adding | 9 * scanning the element model to gather linked information and adding |
| 10 * it to the summary data structures. | 10 * it to the summary data structures. |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 */ | 147 */ |
| 148 bool get isObject; | 148 bool get isObject; |
| 149 | 149 |
| 150 @override | 150 @override |
| 151 String get name; | 151 String get name; |
| 152 | 152 |
| 153 @override | 153 @override |
| 154 ConstructorElementForLink get unnamedConstructor; | 154 ConstructorElementForLink get unnamedConstructor; |
| 155 | 155 |
| 156 @override | 156 @override |
| 157 ReferenceableElementForLink getContainedName(name) { | 157 ReferenceableElementForLink getContainedName(String name) { |
| 158 if (_containedNames == null) { | 158 if (_containedNames == null) { |
| 159 _containedNames = <String, ReferenceableElementForLink>{}; | 159 _containedNames = <String, ReferenceableElementForLink>{}; |
| 160 // TODO(paulberry): what's the correct way to handle name conflicts? | 160 // TODO(paulberry): what's the correct way to handle name conflicts? |
| 161 for (ConstructorElementForLink constructor in constructors) { | 161 for (ConstructorElementForLink constructor in constructors) { |
| 162 _containedNames[constructor.name] = constructor; | 162 _containedNames[constructor.name] = constructor; |
| 163 } | 163 } |
| 164 for (FieldElementForLink field in fields) { | 164 for (FieldElementForLink field in fields) { |
| 165 // TODO(paulberry): do we need to handle nonstatic fields for | 165 // TODO(paulberry): do we need to handle nonstatic fields for |
| 166 // consistent behavior with erroneous code? | 166 // consistent behavior with erroneous code? |
| 167 if (field.isStatic) { | 167 if (field.isStatic) { |
| (...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 603 void safeAddDependency(ConstNode target) { | 603 void safeAddDependency(ConstNode target) { |
| 604 if (target != null) { | 604 if (target != null) { |
| 605 dependencies.add(target); | 605 dependencies.add(target); |
| 606 } | 606 } |
| 607 } | 607 } |
| 608 UnlinkedExecutable unlinkedExecutable = | 608 UnlinkedExecutable unlinkedExecutable = |
| 609 constructorElement._unlinkedExecutable; | 609 constructorElement._unlinkedExecutable; |
| 610 ClassElementForLink_Class enclosingClass = | 610 ClassElementForLink_Class enclosingClass = |
| 611 constructorElement.enclosingElement; | 611 constructorElement.enclosingElement; |
| 612 ConstructorElementForLink redirectedConstructor = | 612 ConstructorElementForLink redirectedConstructor = |
| 613 _getConstRedirectedConstructor(); | 613 _getFactoryRedirectedConstructor(); |
| 614 if (redirectedConstructor != null) { | 614 if (redirectedConstructor != null) { |
| 615 if (redirectedConstructor._constNode != null) { | 615 if (redirectedConstructor._constNode != null) { |
| 616 safeAddDependency(redirectedConstructor._constNode); | 616 safeAddDependency(redirectedConstructor._constNode); |
| 617 } | 617 } |
| 618 } else if (unlinkedExecutable.isFactory) { | 618 } else if (unlinkedExecutable.isFactory) { |
| 619 // Factory constructor, but getConstRedirectedConstructor returned | 619 // Factory constructor, but getConstRedirectedConstructor returned |
| 620 // null. This can happen if we're visiting one of the special external | 620 // null. This can happen if we're visiting one of the special external |
| 621 // const factory constructors in the SDK, or if the code contains | 621 // const factory constructors in the SDK, or if the code contains |
| 622 // errors (such as delegating to a non-const constructor, or delegating | 622 // errors (such as delegating to a non-const constructor, or delegating |
| 623 // to a constructor that can't be resolved). In any of these cases, | 623 // to a constructor that can't be resolved). In any of these cases, |
| 624 // we'll evaluate calls to this constructor without having to refer to | 624 // we'll evaluate calls to this constructor without having to refer to |
| 625 // any other constants. So we don't need to report any dependencies. | 625 // any other constants. So we don't need to report any dependencies. |
| 626 } else { | 626 } else { |
| 627 ClassElementForLink superClass = enclosingClass.supertype?.element; | 627 ClassElementForLink superClass = enclosingClass.supertype?.element; |
| 628 bool superInvocationFound = false; | 628 bool defaultSuperInvocationNeeded = true; |
| 629 for (UnlinkedConstructorInitializer constructorInitializer | 629 for (UnlinkedConstructorInitializer constructorInitializer |
| 630 in constructorElement._unlinkedExecutable.constantInitializers) { | 630 in constructorElement._unlinkedExecutable.constantInitializers) { |
| 631 if (constructorInitializer.kind == | 631 if (constructorInitializer.kind == |
| 632 UnlinkedConstructorInitializerKind.superInvocation) { | 632 UnlinkedConstructorInitializerKind.superInvocation) { |
| 633 superInvocationFound = true; | 633 defaultSuperInvocationNeeded = false; |
| 634 if (superClass != null && !superClass.isObject) { | 634 if (superClass != null && !superClass.isObject) { |
| 635 ConstructorElementForLink constructor = superClass | 635 ConstructorElementForLink constructor = superClass |
| 636 .getContainedName(constructorInitializer.name) | 636 .getContainedName(constructorInitializer.name) |
| 637 .asConstructor; | 637 .asConstructor; |
| 638 safeAddDependency(constructor?._constNode); | 638 safeAddDependency(constructor?._constNode); |
| 639 } | 639 } |
| 640 } else if (constructorInitializer.kind == |
| 641 UnlinkedConstructorInitializerKind.thisInvocation) { |
| 642 defaultSuperInvocationNeeded = false; |
| 643 ConstructorElementForLink constructor = constructorElement |
| 644 .enclosingElement |
| 645 .getContainedName(constructorInitializer.name) |
| 646 .asConstructor; |
| 647 safeAddDependency(constructor?._constNode); |
| 640 } | 648 } |
| 641 CompilationUnitElementForLink compilationUnit = | 649 CompilationUnitElementForLink compilationUnit = |
| 642 constructorElement.enclosingElement.enclosingElement; | 650 constructorElement.enclosingElement.enclosingElement; |
| 643 collectDependencies( | 651 collectDependencies( |
| 644 dependencies, constructorInitializer.expression, compilationUnit); | 652 dependencies, constructorInitializer.expression, compilationUnit); |
| 645 constructorInitializer.arguments.map((UnlinkedConst unlinkedConst) => | 653 constructorInitializer.arguments.map((UnlinkedConst unlinkedConst) => |
| 646 collectDependencies(dependencies, unlinkedConst, compilationUnit)); | 654 collectDependencies(dependencies, unlinkedConst, compilationUnit)); |
| 647 } | 655 } |
| 648 | 656 |
| 649 if (!superInvocationFound) { | 657 if (defaultSuperInvocationNeeded) { |
| 650 // No explicit superconstructor invocation found, so we need to | 658 // No explicit superconstructor invocation found, so we need to |
| 651 // manually insert a reference to the implicit superconstructor. | 659 // manually insert a reference to the implicit superconstructor. |
| 652 if (superClass != null && !superClass.isObject) { | 660 if (superClass != null && !superClass.isObject) { |
| 653 ConstructorElementForLink unnamedConstructor = | 661 ConstructorElementForLink unnamedConstructor = |
| 654 superClass.unnamedConstructor; | 662 superClass.unnamedConstructor; |
| 655 safeAddDependency(unnamedConstructor?._constNode); | 663 safeAddDependency(unnamedConstructor?._constNode); |
| 656 } | 664 } |
| 657 } | 665 } |
| 658 for (FieldElementForLink field in enclosingClass.fields) { | 666 for (FieldElementForLink field in enclosingClass.fields) { |
| 659 // Note: non-static const isn't allowed but we handle it anyway so | 667 // Note: non-static const isn't allowed but we handle it anyway so |
| 660 // that we won't be confused by incorrect code. | 668 // that we won't be confused by incorrect code. |
| 661 if ((field.isFinal || field.isConst) && !field.isStatic) { | 669 if ((field.isFinal || field.isConst) && !field.isStatic) { |
| 662 safeAddDependency(field.asConstVariable); | 670 safeAddDependency(field.asConstVariable); |
| 663 } | 671 } |
| 664 } | 672 } |
| 665 for (ParameterElementForLink parameterElement | 673 for (ParameterElementForLink parameterElement |
| 666 in constructorElement.parameters) { | 674 in constructorElement.parameters) { |
| 667 safeAddDependency(parameterElement._constNode); | 675 safeAddDependency(parameterElement._constNode); |
| 668 } | 676 } |
| 669 } | 677 } |
| 670 return dependencies; | 678 return dependencies; |
| 671 } | 679 } |
| 672 | 680 |
| 673 /** | 681 /** |
| 674 * If [constructorElement] redirects to another constructor, return | 682 * If [constructorElement] redirects to another constructor via a factory |
| 675 * the constructor it redirects to. | 683 * redirect, return the constructor it redirects to. |
| 676 */ | 684 */ |
| 677 ConstructorElementForLink _getConstRedirectedConstructor() { | 685 ConstructorElementForLink _getFactoryRedirectedConstructor() { |
| 678 // TODO(paulberry): implement | 686 EntityRef redirectedConstructor = |
| 679 return null; | 687 constructorElement._unlinkedExecutable.redirectedConstructor; |
| 688 if (redirectedConstructor != null) { |
| 689 return constructorElement.enclosingElement.enclosingElement |
| 690 ._resolveRef(redirectedConstructor.reference) |
| 691 .asConstructor; |
| 692 } else { |
| 693 return null; |
| 694 } |
| 680 } | 695 } |
| 681 } | 696 } |
| 682 | 697 |
| 683 /** | 698 /** |
| 684 * Specialization of [DependencyWalker] for detecting constant | 699 * Specialization of [DependencyWalker] for detecting constant |
| 685 * evaluation cycles. | 700 * evaluation cycles. |
| 686 */ | 701 */ |
| 687 class ConstDependencyWalker extends DependencyWalker<ConstNode> { | 702 class ConstDependencyWalker extends DependencyWalker<ConstNode> { |
| 688 @override | 703 @override |
| 689 void evaluate(ConstNode v) { | 704 void evaluate(ConstNode v) { |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 838 } | 853 } |
| 839 return _parameters; | 854 return _parameters; |
| 840 } | 855 } |
| 841 | 856 |
| 842 @override | 857 @override |
| 843 DartTypeForLink buildType(DartTypeForLink getTypeArgument(int i), | 858 DartTypeForLink buildType(DartTypeForLink getTypeArgument(int i), |
| 844 List<int> implicitFunctionTypeIndices) => | 859 List<int> implicitFunctionTypeIndices) => |
| 845 DynamicTypeForLink.instance; | 860 DynamicTypeForLink.instance; |
| 846 | 861 |
| 847 @override | 862 @override |
| 848 ReferenceableElementForLink getContainedName(name) => | 863 ReferenceableElementForLink getContainedName(String name) => |
| 849 UndefinedElementForLink.instance; | 864 UndefinedElementForLink.instance; |
| 850 | 865 |
| 851 /** | 866 /** |
| 852 * Perform const cycle detection on this constructor. | 867 * Perform const cycle detection on this constructor. |
| 853 */ | 868 */ |
| 854 void link(LinkedUnitBuilder linkedUnit) { | 869 void link(LinkedUnitBuilder linkedUnit) { |
| 855 if (_constNode != null && !isCycleFree) { | 870 if (_constNode != null && !isCycleFree) { |
| 856 linkedUnit.constCycles.add(_unlinkedExecutable.constCycleSlot); | 871 linkedUnit.constCycles.add(_unlinkedExecutable.constCycleSlot); |
| 857 } | 872 } |
| 858 } | 873 } |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1099 @override | 1114 @override |
| 1100 String get name => | 1115 String get name => |
| 1101 unlinkedEnumValue == null ? 'values' : unlinkedEnumValue.name; | 1116 unlinkedEnumValue == null ? 'values' : unlinkedEnumValue.name; |
| 1102 | 1117 |
| 1103 @override | 1118 @override |
| 1104 DartTypeForLink buildType(DartTypeForLink getTypeArgument(int i), | 1119 DartTypeForLink buildType(DartTypeForLink getTypeArgument(int i), |
| 1105 List<int> implicitFunctionTypeIndices) => | 1120 List<int> implicitFunctionTypeIndices) => |
| 1106 DynamicTypeForLink.instance; | 1121 DynamicTypeForLink.instance; |
| 1107 | 1122 |
| 1108 @override | 1123 @override |
| 1109 ReferenceableElementForLink getContainedName(name) => | 1124 ReferenceableElementForLink getContainedName(String name) => |
| 1110 UndefinedElementForLink.instance; | 1125 UndefinedElementForLink.instance; |
| 1111 | 1126 |
| 1112 @override | 1127 @override |
| 1113 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); | 1128 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); |
| 1114 } | 1129 } |
| 1115 | 1130 |
| 1116 /** | 1131 /** |
| 1117 * Representation of an interface type during linking. | 1132 * Representation of an interface type during linking. |
| 1118 * | 1133 * |
| 1119 * TODO(paulberry): add the ability to represent type arguments. | 1134 * TODO(paulberry): add the ability to represent type arguments. |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1369 DartTypeForLink buildType(DartTypeForLink getTypeArgument(int i), | 1384 DartTypeForLink buildType(DartTypeForLink getTypeArgument(int i), |
| 1370 List<int> implicitFunctionTypeIndices); | 1385 List<int> implicitFunctionTypeIndices); |
| 1371 | 1386 |
| 1372 /** | 1387 /** |
| 1373 * If this element contains other named elements, return the | 1388 * If this element contains other named elements, return the |
| 1374 * contained element having the given [name]. If this element can't | 1389 * contained element having the given [name]. If this element can't |
| 1375 * contain other named elements, or it doesn't contain an element | 1390 * contain other named elements, or it doesn't contain an element |
| 1376 * with the given name, return the singleton of | 1391 * with the given name, return the singleton of |
| 1377 * [UndefinedElementForLink]. | 1392 * [UndefinedElementForLink]. |
| 1378 */ | 1393 */ |
| 1379 ReferenceableElementForLink getContainedName(name); | 1394 ReferenceableElementForLink getContainedName(String name); |
| 1380 } | 1395 } |
| 1381 | 1396 |
| 1382 /** | 1397 /** |
| 1383 * Element representing a top level variable resynthesized from a | 1398 * Element representing a top level variable resynthesized from a |
| 1384 * summary during linking. | 1399 * summary during linking. |
| 1385 */ | 1400 */ |
| 1386 class TopLevelVariableElementForLink extends VariableElementForLink | 1401 class TopLevelVariableElementForLink extends VariableElementForLink |
| 1387 implements TopLevelVariableElement { | 1402 implements TopLevelVariableElement { |
| 1388 TopLevelVariableElementForLink(CompilationUnitElement enclosingElement, | 1403 TopLevelVariableElementForLink(CompilationUnitElement enclosingElement, |
| 1389 UnlinkedVariable unlinkedVariable) | 1404 UnlinkedVariable unlinkedVariable) |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1426 | 1441 |
| 1427 @override | 1442 @override |
| 1428 ConstVariableNode get asConstVariable => null; | 1443 ConstVariableNode get asConstVariable => null; |
| 1429 | 1444 |
| 1430 @override | 1445 @override |
| 1431 DartTypeForLink buildType(DartTypeForLink getTypeArgument(int i), | 1446 DartTypeForLink buildType(DartTypeForLink getTypeArgument(int i), |
| 1432 List<int> implicitFunctionTypeIndices) => | 1447 List<int> implicitFunctionTypeIndices) => |
| 1433 DynamicTypeForLink.instance; | 1448 DynamicTypeForLink.instance; |
| 1434 | 1449 |
| 1435 @override | 1450 @override |
| 1436 ReferenceableElementForLink getContainedName(name) => this; | 1451 ReferenceableElementForLink getContainedName(String name) => this; |
| 1437 } | 1452 } |
| 1438 | 1453 |
| 1439 /** | 1454 /** |
| 1440 * Element representing a top level variable resynthesized from a | 1455 * Element representing a top level variable resynthesized from a |
| 1441 * summary during linking. | 1456 * summary during linking. |
| 1442 */ | 1457 */ |
| 1443 class VariableElementForLink | 1458 class VariableElementForLink |
| 1444 implements VariableElement, ReferenceableElementForLink { | 1459 implements VariableElement, ReferenceableElementForLink { |
| 1445 /** | 1460 /** |
| 1446 * The unlinked representation of the variable in the summary. | 1461 * The unlinked representation of the variable in the summary. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1481 bool get isStatic; | 1496 bool get isStatic; |
| 1482 | 1497 |
| 1483 @override | 1498 @override |
| 1484 String get name => unlinkedVariable.name; | 1499 String get name => unlinkedVariable.name; |
| 1485 | 1500 |
| 1486 @override | 1501 @override |
| 1487 DartTypeForLink buildType(DartTypeForLink getTypeArgument(int i), | 1502 DartTypeForLink buildType(DartTypeForLink getTypeArgument(int i), |
| 1488 List<int> implicitFunctionTypeIndices) => | 1503 List<int> implicitFunctionTypeIndices) => |
| 1489 DynamicTypeForLink.instance; | 1504 DynamicTypeForLink.instance; |
| 1490 | 1505 |
| 1491 ReferenceableElementForLink getContainedName(name) { | 1506 ReferenceableElementForLink getContainedName(String name) { |
| 1492 // TODO(paulberry): implement. | 1507 // TODO(paulberry): implement. |
| 1493 // TODO(paulberry): make sure that circularities involving | 1508 // TODO(paulberry): make sure that circularities involving |
| 1494 // ".length" are handled correctly. | 1509 // ".length" are handled correctly. |
| 1495 return UndefinedElementForLink.instance; | 1510 return UndefinedElementForLink.instance; |
| 1496 } | 1511 } |
| 1497 | 1512 |
| 1498 @override | 1513 @override |
| 1499 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); | 1514 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); |
| 1500 } | 1515 } |
| 1501 | 1516 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1587 | 1602 |
| 1588 /** | 1603 /** |
| 1589 * Throw away any information produced by a previous call to [link]. | 1604 * Throw away any information produced by a previous call to [link]. |
| 1590 */ | 1605 */ |
| 1591 void unlink() { | 1606 void unlink() { |
| 1592 for (LibraryElementInBuildUnit library in _librariesInBuildUnit) { | 1607 for (LibraryElementInBuildUnit library in _librariesInBuildUnit) { |
| 1593 library.unlink(); | 1608 library.unlink(); |
| 1594 } | 1609 } |
| 1595 } | 1610 } |
| 1596 } | 1611 } |
| OLD | NEW |