| OLD | NEW |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 part of world_builder; | 5 part of world_builder; |
| 6 | 6 |
| 7 abstract class ResolutionWorldBuilder implements WorldBuilder, OpenWorld { | 7 abstract class ResolutionWorldBuilder implements WorldBuilder, OpenWorld { |
| 8 /// Set of all local functions in the program. Used by the mirror tracking | 8 /// Set of all local functions in the program. Used by the mirror tracking |
| 9 /// system to find all live closure instances. | 9 /// system to find all live closure instances. |
| 10 Iterable<Local> get localFunctions; | 10 Iterable<Local> get localFunctions; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 /// | 22 /// |
| 23 /// A closurized method is considered live if the enclosing class has been | 23 /// A closurized method is considered live if the enclosing class has been |
| 24 /// instantiated. | 24 /// instantiated. |
| 25 Iterable<FunctionEntity> get closurizedMembersWithFreeTypeVariables; | 25 Iterable<FunctionEntity> get closurizedMembersWithFreeTypeVariables; |
| 26 | 26 |
| 27 /// Returns `true` if [cls] is considered to be implemented by an | 27 /// Returns `true` if [cls] is considered to be implemented by an |
| 28 /// instantiated class, either directly, through subclasses or through | 28 /// instantiated class, either directly, through subclasses or through |
| 29 /// subtypes. The latter case only contains spurious information from | 29 /// subtypes. The latter case only contains spurious information from |
| 30 /// instantiations through factory constructors and mixins. | 30 /// instantiations through factory constructors and mixins. |
| 31 // TODO(johnniwinther): Improve semantic precision. | 31 // TODO(johnniwinther): Improve semantic precision. |
| 32 bool isImplemented(ClassEntity cls); | 32 bool isImplemented(covariant ClassEntity cls); |
| 33 | 33 |
| 34 /// Set of all fields that are statically known to be written to. | 34 /// Set of all fields that are statically known to be written to. |
| 35 Iterable<FieldEntity> get fieldSetters; | 35 Iterable<FieldEntity> get fieldSetters; |
| 36 | 36 |
| 37 /// Call [f] for all classes with instantiated types. This includes the | 37 /// Call [f] for all classes with instantiated types. This includes the |
| 38 /// directly and abstractly instantiated classes but also classes whose type | 38 /// directly and abstractly instantiated classes but also classes whose type |
| 39 /// arguments are used in live factory constructors. | 39 /// arguments are used in live factory constructors. |
| 40 void forEachInstantiatedClass(f(ClassEntity cls, InstantiationInfo info)); | 40 void forEachInstantiatedClass(f(ClassEntity cls, InstantiationInfo info)); |
| 41 | 41 |
| 42 /// Returns `true` if [member] is invoked as a setter. | 42 /// Returns `true` if [member] is invoked as a setter. |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 424 } | 424 } |
| 425 } | 425 } |
| 426 }); | 426 }); |
| 427 return types; | 427 return types; |
| 428 } | 428 } |
| 429 | 429 |
| 430 bool isImplemented(ClassEntity cls) { | 430 bool isImplemented(ClassEntity cls) { |
| 431 return _implementedClasses.contains(cls); | 431 return _implementedClasses.contains(cls); |
| 432 } | 432 } |
| 433 | 433 |
| 434 void registerClosurizedMember(FunctionEntity element) { | 434 void registerClosurizedMember(MemberEntity element) { |
| 435 closurizedMembers.add(element); | 435 closurizedMembers.add(element); |
| 436 FunctionType type = _elementEnvironment.getFunctionType(element); | 436 FunctionType type = _elementEnvironment.getFunctionType(element); |
| 437 if (type.containsTypeVariables) { | 437 if (type.containsTypeVariables) { |
| 438 closurizedMembersWithFreeTypeVariables.add(element); | 438 closurizedMembersWithFreeTypeVariables.add(element); |
| 439 } | 439 } |
| 440 } | 440 } |
| 441 | 441 |
| 442 /// Register [type] as (directly) instantiated. | 442 /// Register [type] as (directly) instantiated. |
| 443 /// | 443 /// |
| 444 /// If [byMirrors] is `true`, the instantiation is through mirrors. | 444 /// If [byMirrors] is `true`, the instantiation is through mirrors. |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 568 ReceiverConstraint mask = dynamicUse.mask; | 568 ReceiverConstraint mask = dynamicUse.mask; |
| 569 Map<Selector, SelectorConstraints> selectors = selectorMap.putIfAbsent( | 569 Map<Selector, SelectorConstraints> selectors = selectorMap.putIfAbsent( |
| 570 name, () => new Maplet<Selector, SelectorConstraints>()); | 570 name, () => new Maplet<Selector, SelectorConstraints>()); |
| 571 UniverseSelectorConstraints constraints = | 571 UniverseSelectorConstraints constraints = |
| 572 selectors.putIfAbsent(selector, () { | 572 selectors.putIfAbsent(selector, () { |
| 573 return selectorConstraintsStrategy.createSelectorConstraints(selector); | 573 return selectorConstraintsStrategy.createSelectorConstraints(selector); |
| 574 }); | 574 }); |
| 575 return constraints.addReceiverConstraint(mask); | 575 return constraints.addReceiverConstraint(mask); |
| 576 } | 576 } |
| 577 | 577 |
| 578 void registerIsCheck(DartType type) { | 578 void registerIsCheck(covariant DartType type) { |
| 579 isChecks.add(type); | 579 isChecks.add(type); |
| 580 } | 580 } |
| 581 | 581 |
| 582 bool registerConstantUse(ConstantUse use) { | 582 bool registerConstantUse(ConstantUse use) { |
| 583 return _constantValues.add(use.value); | 583 return _constantValues.add(use.value); |
| 584 } | 584 } |
| 585 | 585 |
| 586 void registerStaticUse(StaticUse staticUse, MemberUsedCallback memberUsed) { | 586 void registerStaticUse(StaticUse staticUse, MemberUsedCallback memberUsed) { |
| 587 if (staticUse.kind == StaticUseKind.CLOSURE) { | 587 if (staticUse.kind == StaticUseKind.CLOSURE) { |
| 588 Local localFunction = staticUse.element; | 588 Local localFunction = staticUse.element; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 647 "Static use ${staticUse.kind} is not supported during resolution."); | 647 "Static use ${staticUse.kind} is not supported during resolution."); |
| 648 } | 648 } |
| 649 if (useSet.isNotEmpty) { | 649 if (useSet.isNotEmpty) { |
| 650 memberUsed(usage.entity, useSet); | 650 memberUsed(usage.entity, useSet); |
| 651 } | 651 } |
| 652 } | 652 } |
| 653 | 653 |
| 654 /// Called to create a [_ClassUsage] for [cls]. | 654 /// Called to create a [_ClassUsage] for [cls]. |
| 655 /// | 655 /// |
| 656 /// Subclasses override this to ensure needed invariants on [cls]. | 656 /// Subclasses override this to ensure needed invariants on [cls]. |
| 657 _ClassUsage _createClassUsage(ClassEntity cls) => new _ClassUsage(cls); | 657 _ClassUsage _createClassUsage(covariant ClassEntity cls) => |
| 658 new _ClassUsage(cls); |
| 658 | 659 |
| 659 /// Return the canonical [_ClassUsage] for [cls]. | 660 /// Return the canonical [_ClassUsage] for [cls]. |
| 660 _ClassUsage _getClassUsage(ClassEntity cls) { | 661 _ClassUsage _getClassUsage(ClassEntity cls) { |
| 661 return _processedClasses.putIfAbsent(cls, () { | 662 return _processedClasses.putIfAbsent(cls, () { |
| 662 return _createClassUsage(cls); | 663 return _createClassUsage(cls); |
| 663 }); | 664 }); |
| 664 } | 665 } |
| 665 | 666 |
| 666 /// Register [cls] and all its superclasses as instantiated. | 667 /// Register [cls] and all its superclasses as instantiated. |
| 667 void _processInstantiatedClass(ClassEntity cls, ClassUsedCallback classUsed) { | 668 void _processInstantiatedClass(ClassEntity cls, ClassUsedCallback classUsed) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 702 // so we create a new list for [: map[memberName] :] and prepend the | 703 // so we create a new list for [: map[memberName] :] and prepend the |
| 703 // [remaining] members after the loop. | 704 // [remaining] members after the loop. |
| 704 map[memberName] = new Set<_MemberUsage>(); | 705 map[memberName] = new Set<_MemberUsage>(); |
| 705 Set<_MemberUsage> remaining = new Set<_MemberUsage>(); | 706 Set<_MemberUsage> remaining = new Set<_MemberUsage>(); |
| 706 for (_MemberUsage usage in members) { | 707 for (_MemberUsage usage in members) { |
| 707 if (!updateUsage(usage)) remaining.add(usage); | 708 if (!updateUsage(usage)) remaining.add(usage); |
| 708 } | 709 } |
| 709 map[memberName].addAll(remaining); | 710 map[memberName].addAll(remaining); |
| 710 } | 711 } |
| 711 | 712 |
| 712 void _processInstantiatedClassMember( | 713 void _processInstantiatedClassMember(ClassEntity cls, |
| 713 ClassEntity cls, MemberEntity member, MemberUsedCallback memberUsed) { | 714 covariant MemberEntity member, MemberUsedCallback memberUsed) { |
| 714 if (!member.isInstanceMember) return; | 715 if (!member.isInstanceMember) return; |
| 715 String memberName = member.name; | 716 String memberName = member.name; |
| 716 // The obvious thing to test here would be "member.isNative", | 717 // The obvious thing to test here would be "member.isNative", |
| 717 // however, that only works after metadata has been parsed/analyzed, | 718 // however, that only works after metadata has been parsed/analyzed, |
| 718 // and that may not have happened yet. | 719 // and that may not have happened yet. |
| 719 // So instead we use the enclosing class, which we know have had | 720 // So instead we use the enclosing class, which we know have had |
| 720 // its metadata parsed and analyzed. | 721 // its metadata parsed and analyzed. |
| 721 // Note: this assumes that there are no non-native fields on native | 722 // Note: this assumes that there are no non-native fields on native |
| 722 // classes, which may not be the case when a native class is subclassed. | 723 // classes, which may not be the case when a native class is subclassed. |
| 723 _instanceMemberUsage.putIfAbsent(member, () { | 724 _instanceMemberUsage.putIfAbsent(member, () { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 767 /// Returns an iterable over all mixin applications that mixin [cls]. | 768 /// Returns an iterable over all mixin applications that mixin [cls]. |
| 768 Iterable<ClassEntity> allMixinUsesOf(ClassEntity cls) { | 769 Iterable<ClassEntity> allMixinUsesOf(ClassEntity cls) { |
| 769 Iterable<ClassEntity> uses = _mixinUses[cls]; | 770 Iterable<ClassEntity> uses = _mixinUses[cls]; |
| 770 return uses != null ? uses : const <ClassEntity>[]; | 771 return uses != null ? uses : const <ClassEntity>[]; |
| 771 } | 772 } |
| 772 | 773 |
| 773 void registerTypedef(TypedefElement typdef) { | 774 void registerTypedef(TypedefElement typdef) { |
| 774 _allTypedefs.add(typdef); | 775 _allTypedefs.add(typdef); |
| 775 } | 776 } |
| 776 | 777 |
| 777 void registerMixinUse(ClassEntity mixinApplication, ClassEntity mixin) { | 778 void registerMixinUse( |
| 779 covariant ClassEntity mixinApplication, covariant ClassEntity mixin) { |
| 778 // TODO(johnniwinther): Add map restricted to live classes. | 780 // TODO(johnniwinther): Add map restricted to live classes. |
| 779 // We don't support patch classes as mixin. | 781 // We don't support patch classes as mixin. |
| 780 Set<ClassEntity> users = | 782 Set<ClassEntity> users = |
| 781 _mixinUses.putIfAbsent(mixin, () => new Set<ClassEntity>()); | 783 _mixinUses.putIfAbsent(mixin, () => new Set<ClassEntity>()); |
| 782 users.add(mixinApplication); | 784 users.add(mixinApplication); |
| 783 } | 785 } |
| 784 | 786 |
| 785 void registerUsedElement(MemberEntity element) { | 787 void registerUsedElement(MemberEntity element) { |
| 786 if (element.isInstanceMember && !element.isAbstract) { | 788 if (element.isInstanceMember && !element.isAbstract) { |
| 787 _allFunctions.add(element); | 789 _allFunctions.add(element); |
| 788 } | 790 } |
| 789 } | 791 } |
| 790 | 792 |
| 791 ClosedWorld get closedWorldCache { | 793 ClosedWorld get closedWorldCache { |
| 792 assert(isClosed); | 794 assert(isClosed); |
| 793 return _closedWorldCache; | 795 return _closedWorldCache; |
| 794 } | 796 } |
| 795 | 797 |
| 796 @override | 798 @override |
| 797 bool isMemberUsed(MemberEntity member) { | 799 bool isMemberUsed(MemberEntity member) { |
| 798 if (member.isInstanceMember) { | 800 if (member.isInstanceMember) { |
| 799 _MemberUsage usage = _instanceMemberUsage[member]; | 801 _MemberUsage usage = _instanceMemberUsage[member]; |
| 800 if (usage != null && usage.hasUse) return true; | 802 if (usage != null && usage.hasUse) return true; |
| 801 } | 803 } |
| 802 _StaticMemberUsage usage = _staticMemberUsage[member]; | 804 _StaticMemberUsage usage = _staticMemberUsage[member]; |
| 803 return usage != null && usage.hasUse; | 805 return usage != null && usage.hasUse; |
| 804 } | 806 } |
| 805 | 807 |
| 806 bool checkClass(ClassEntity cls); | 808 bool checkClass(covariant ClassEntity cls); |
| 807 bool validateClass(ClassEntity cls); | 809 bool validateClass(covariant ClassEntity cls); |
| 808 | 810 |
| 809 /// Returns the class mixed into [cls] if any. | 811 /// Returns the class mixed into [cls] if any. |
| 810 ClassEntity getAppliedMixin(ClassEntity cls); | 812 ClassEntity getAppliedMixin(covariant ClassEntity cls); |
| 811 | 813 |
| 812 /// Returns the hierarchy depth of [cls]. | 814 /// Returns the hierarchy depth of [cls]. |
| 813 int getHierarchyDepth(ClassEntity cls); | 815 int getHierarchyDepth(covariant ClassEntity cls); |
| 814 | 816 |
| 815 /// Returns `true` if [cls] implements `Function` either explicitly or through | 817 /// Returns `true` if [cls] implements `Function` either explicitly or through |
| 816 /// a `call` method. | 818 /// a `call` method. |
| 817 bool implementsFunction(ClassEntity cls); | 819 bool implementsFunction(covariant ClassEntity cls); |
| 818 | 820 |
| 819 /// Returns the superclass of [cls] if any. | 821 /// Returns the superclass of [cls] if any. |
| 820 ClassEntity getSuperClass(ClassEntity cls); | 822 ClassEntity getSuperClass(covariant ClassEntity cls); |
| 821 | 823 |
| 822 /// Returns all supertypes of [cls]. | 824 /// Returns all supertypes of [cls]. |
| 823 Iterable<InterfaceType> getSupertypes(ClassEntity cls); | 825 Iterable<InterfaceType> getSupertypes(covariant ClassEntity cls); |
| 824 | 826 |
| 825 ClassHierarchyNode _ensureClassHierarchyNode(ClassEntity cls) { | 827 ClassHierarchyNode _ensureClassHierarchyNode(ClassEntity cls) { |
| 826 assert(checkClass(cls)); | 828 assert(checkClass(cls)); |
| 827 return _classHierarchyNodes.putIfAbsent(cls, () { | 829 return _classHierarchyNodes.putIfAbsent(cls, () { |
| 828 ClassHierarchyNode parentNode; | 830 ClassHierarchyNode parentNode; |
| 829 ClassEntity superclass = getSuperClass(cls); | 831 ClassEntity superclass = getSuperClass(cls); |
| 830 if (superclass != null) { | 832 if (superclass != null) { |
| 831 parentNode = _ensureClassHierarchyNode(superclass); | 833 parentNode = _ensureClassHierarchyNode(superclass); |
| 832 } | 834 } |
| 833 return new ClassHierarchyNode(parentNode, cls, getHierarchyDepth(cls)); | 835 return new ClassHierarchyNode(parentNode, cls, getHierarchyDepth(cls)); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 977 typesImplementedBySubclasses: typesImplementedBySubclasses, | 979 typesImplementedBySubclasses: typesImplementedBySubclasses, |
| 978 classHierarchyNodes: _classHierarchyNodes, | 980 classHierarchyNodes: _classHierarchyNodes, |
| 979 classSets: _classSets); | 981 classSets: _classSets); |
| 980 } | 982 } |
| 981 | 983 |
| 982 @override | 984 @override |
| 983 void registerClass(ClassEntity cls) { | 985 void registerClass(ClassEntity cls) { |
| 984 throw new UnimplementedError('KernelResolutionWorldBuilder.registerClass'); | 986 throw new UnimplementedError('KernelResolutionWorldBuilder.registerClass'); |
| 985 } | 987 } |
| 986 } | 988 } |
| OLD | NEW |