| 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 766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 777 | 777 |
| 778 @override | 778 @override |
| 779 bool isMemberUsed(MemberEntity member) { | 779 bool isMemberUsed(MemberEntity member) { |
| 780 if (member.isInstanceMember) { | 780 if (member.isInstanceMember) { |
| 781 _MemberUsage usage = _instanceMemberUsage[member]; | 781 _MemberUsage usage = _instanceMemberUsage[member]; |
| 782 if (usage != null && usage.hasUse) return true; | 782 if (usage != null && usage.hasUse) return true; |
| 783 } | 783 } |
| 784 _StaticMemberUsage usage = _staticMemberUsage[member]; | 784 _StaticMemberUsage usage = _staticMemberUsage[member]; |
| 785 return usage != null && usage.hasUse; | 785 return usage != null && usage.hasUse; |
| 786 } | 786 } |
| 787 |
| 788 bool checkClass(ClassEntity cls); |
| 789 bool validateClass(ClassEntity cls); |
| 790 |
| 791 /// Returns the class mixed into [cls] if any. |
| 792 ClassEntity getAppliedMixin(ClassEntity cls); |
| 793 |
| 794 /// Returns the hierarchy depth of [cls]. |
| 795 int getHierarchyDepth(ClassEntity cls); |
| 796 |
| 797 /// Returns `true` if [cls] implements `Function` either explicitly or through |
| 798 /// a `call` method. |
| 799 bool implementsFunction(ClassEntity cls); |
| 800 |
| 801 /// Returns the superclass of [cls] if any. |
| 802 ClassEntity getSuperClass(ClassEntity cls); |
| 803 |
| 804 /// Returns all supertypes of [cls]. |
| 805 Iterable<InterfaceType> getSupertypes(ClassEntity cls); |
| 806 |
| 807 ClassHierarchyNode _ensureClassHierarchyNode(ClassEntity cls) { |
| 808 assert(checkClass(cls)); |
| 809 return _classHierarchyNodes.putIfAbsent(cls, () { |
| 810 ClassHierarchyNode parentNode; |
| 811 ClassEntity superclass = getSuperClass(cls); |
| 812 if (superclass != null) { |
| 813 parentNode = _ensureClassHierarchyNode(superclass); |
| 814 } |
| 815 return new ClassHierarchyNode(parentNode, cls, getHierarchyDepth(cls)); |
| 816 }); |
| 817 } |
| 818 |
| 819 ClassSet _ensureClassSet(ClassEntity cls) { |
| 820 assert(checkClass(cls)); |
| 821 return _classSets.putIfAbsent(cls, () { |
| 822 ClassHierarchyNode node = _ensureClassHierarchyNode(cls); |
| 823 ClassSet classSet = new ClassSet(node); |
| 824 |
| 825 for (InterfaceType type in getSupertypes(cls)) { |
| 826 // TODO(johnniwinther): Optimization: Avoid adding [cls] to |
| 827 // superclasses. |
| 828 ClassSet subtypeSet = _ensureClassSet(type.element); |
| 829 subtypeSet.addSubtype(node); |
| 830 } |
| 831 |
| 832 ClassEntity appliedMixin = getAppliedMixin(cls); |
| 833 if (appliedMixin != null) { |
| 834 // TODO(johnniwinther): Store this in the [ClassSet]. |
| 835 registerMixinUse(cls, appliedMixin); |
| 836 } |
| 837 |
| 838 return classSet; |
| 839 }); |
| 840 } |
| 841 |
| 842 void _updateSuperClassHierarchyNodeForClass(ClassHierarchyNode node) { |
| 843 // Ensure that classes implicitly implementing `Function` are in its |
| 844 // subtype set. |
| 845 ClassEntity cls = node.cls; |
| 846 if (cls != _commonElements.functionClass && implementsFunction(cls)) { |
| 847 ClassSet subtypeSet = _ensureClassSet(_commonElements.functionClass); |
| 848 subtypeSet.addSubtype(node); |
| 849 } |
| 850 if (!node.isInstantiated && node.parentNode != null) { |
| 851 _updateSuperClassHierarchyNodeForClass(node.parentNode); |
| 852 } |
| 853 } |
| 854 |
| 855 void _updateClassHierarchyNodeForClass(ClassEntity cls, |
| 856 {bool directlyInstantiated: false, bool abstractlyInstantiated: false}) { |
| 857 ClassHierarchyNode node = _ensureClassHierarchyNode(cls); |
| 858 _updateSuperClassHierarchyNodeForClass(node); |
| 859 if (directlyInstantiated) { |
| 860 node.isDirectlyInstantiated = true; |
| 861 } |
| 862 if (abstractlyInstantiated) { |
| 863 node.isAbstractlyInstantiated = true; |
| 864 } |
| 865 } |
| 866 |
| 867 Map<ClassEntity, Set<ClassEntity>> populateHierarchyNodes() { |
| 868 Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses = |
| 869 new Map<ClassEntity, Set<ClassEntity>>(); |
| 870 |
| 871 /// Updates the `isDirectlyInstantiated` and `isIndirectlyInstantiated` |
| 872 /// properties of the [ClassHierarchyNode] for [cls]. |
| 873 |
| 874 void addSubtypes(ClassEntity cls, InstantiationInfo info) { |
| 875 if (!info.hasInstantiation) { |
| 876 return; |
| 877 } |
| 878 assert(checkClass(cls)); |
| 879 if (!validateClass(cls)) { |
| 880 throw new SpannableAssertionFailure( |
| 881 cls, 'Class "${cls.name}" is not resolved.'); |
| 882 } |
| 883 |
| 884 _updateClassHierarchyNodeForClass(cls, |
| 885 directlyInstantiated: info.isDirectlyInstantiated, |
| 886 abstractlyInstantiated: info.isAbstractlyInstantiated); |
| 887 |
| 888 // Walk through the superclasses, and record the types |
| 889 // implemented by that type on the superclasses. |
| 890 ClassEntity superclass = getSuperClass(cls); |
| 891 while (superclass != null) { |
| 892 Set<ClassEntity> typesImplementedBySubclassesOfCls = |
| 893 typesImplementedBySubclasses.putIfAbsent( |
| 894 superclass, () => new Set<ClassEntity>()); |
| 895 for (InterfaceType current in getSupertypes(cls)) { |
| 896 typesImplementedBySubclassesOfCls.add(current.element); |
| 897 } |
| 898 superclass = getSuperClass(superclass); |
| 899 } |
| 900 } |
| 901 |
| 902 // Use the [:seenClasses:] set to include non-instantiated |
| 903 // classes: if the superclass of these classes require RTI, then |
| 904 // they also need RTI, so that a constructor passes the type |
| 905 // variables to the super constructor. |
| 906 forEachInstantiatedClass(addSubtypes); |
| 907 |
| 908 return typesImplementedBySubclasses; |
| 909 } |
| 787 } | 910 } |
| 788 | 911 |
| 789 class KernelResolutionWorldBuilder extends ResolutionWorldBuilderBase { | 912 abstract class KernelResolutionWorldBuilderBase |
| 790 KernelResolutionWorldBuilder( | 913 extends ResolutionWorldBuilderBase { |
| 914 KernelResolutionWorldBuilderBase( |
| 791 ElementEnvironment elementEnvironment, | 915 ElementEnvironment elementEnvironment, |
| 792 CommonElements commonElements, | 916 CommonElements commonElements, |
| 793 NativeBasicData nativeBasicData, | 917 NativeBasicData nativeBasicData, |
| 794 SelectorConstraintsStrategy selectorConstraintsStrategy) | 918 SelectorConstraintsStrategy selectorConstraintsStrategy) |
| 795 : super(elementEnvironment, commonElements, nativeBasicData, | 919 : super(elementEnvironment, commonElements, nativeBasicData, |
| 796 selectorConstraintsStrategy); | 920 selectorConstraintsStrategy); |
| 797 | 921 |
| 798 @override | 922 @override |
| 799 ClosedWorld closeWorld() { | 923 ClosedWorld closeWorld() { |
| 924 Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses = |
| 925 populateHierarchyNodes(); |
| 926 _closed = true; |
| 800 // TODO(johnniwinther): Implement this. | 927 // TODO(johnniwinther): Implement this. |
| 801 return _closedWorldCache = new KernelClosedWorld( | 928 return _closedWorldCache = new KernelClosedWorld( |
| 802 commonElements: _commonElements, | 929 commonElements: _commonElements, |
| 803 // TODO(johnniwinther): Compute these. | 930 // TODO(johnniwinther): Compute these. |
| 804 constantSystem: null, | 931 constantSystem: null, |
| 805 nativeData: null, | 932 nativeData: null, |
| 806 interceptorData: null, | 933 interceptorData: null, |
| 807 backendUsage: null, | 934 backendUsage: null, |
| 808 resolutionWorldBuilder: this, | 935 resolutionWorldBuilder: this, |
| 809 functionSetBuilder: _allFunctions, | 936 functionSetBuilder: _allFunctions, |
| 810 allTypedefs: _allTypedefs, | 937 allTypedefs: _allTypedefs, |
| 811 mixinUses: _mixinUses, | 938 mixinUses: _mixinUses, |
| 812 // TODO(johnniwinther): Compute this. | 939 typesImplementedBySubclasses: typesImplementedBySubclasses, |
| 813 typesImplementedBySubclasses: null, | |
| 814 classHierarchyNodes: _classHierarchyNodes, | 940 classHierarchyNodes: _classHierarchyNodes, |
| 815 classSets: _classSets); | 941 classSets: _classSets); |
| 816 } | 942 } |
| 817 | 943 |
| 818 @override | 944 @override |
| 819 void registerClass(ClassEntity cls) { | 945 void registerClass(ClassEntity cls) { |
| 820 throw new UnimplementedError('KernelResolutionWorldBuilder.registerClass'); | 946 throw new UnimplementedError('KernelResolutionWorldBuilder.registerClass'); |
| 821 } | 947 } |
| 822 } | 948 } |
| OLD | NEW |