Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: pkg/analyzer/lib/src/summary/link.dart

Issue 1840843003: Handle redirected constructors when generating summaries from ASTs. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | pkg/analyzer/test/src/summary/summary_common.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/src/summary/summary_common.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698