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 |