| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 library dart2js.world; | 5 library dart2js.world; |
| 6 | 6 |
| 7 import 'closure.dart' show ClosureClassElement, SynthesizedCallMethodElementX; | 7 import 'closure.dart' show ClosureClassElement, SynthesizedCallMethodElementX; |
| 8 import 'common/backend_api.dart' show BackendClasses; | 8 import 'common/backend_api.dart' show BackendClasses; |
| 9 import 'common.dart'; | 9 import 'common.dart'; |
| 10 import 'constants/constant_system.dart'; | 10 import 'constants/constant_system.dart'; |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 ClassEntity getLubOfInstantiatedSubclasses(ClassEntity cls); | 153 ClassEntity getLubOfInstantiatedSubclasses(ClassEntity cls); |
| 154 | 154 |
| 155 /// Returns the most specific subtype of [cls] (including [cls]) that is | 155 /// Returns the most specific subtype of [cls] (including [cls]) that is |
| 156 /// directly instantiated or a superclass of all directly instantiated | 156 /// directly instantiated or a superclass of all directly instantiated |
| 157 /// subtypes. If no subtypes of [cls] are instantiated, `null` is returned. | 157 /// subtypes. If no subtypes of [cls] are instantiated, `null` is returned. |
| 158 ClassEntity getLubOfInstantiatedSubtypes(ClassEntity cls); | 158 ClassEntity getLubOfInstantiatedSubtypes(ClassEntity cls); |
| 159 | 159 |
| 160 /// Returns an iterable over the common supertypes of the [classes]. | 160 /// Returns an iterable over the common supertypes of the [classes]. |
| 161 Iterable<ClassEntity> commonSupertypesOf(Iterable<ClassEntity> classes); | 161 Iterable<ClassEntity> commonSupertypesOf(Iterable<ClassEntity> classes); |
| 162 | 162 |
| 163 /// Returns an iterable of the classes that are contained in the |
| 164 /// strict subclass/subtype sets of both [cls1] and [cls2]. |
| 165 /// |
| 166 /// Classes that are implied by included superclasses/supertypes are not |
| 167 /// returned. |
| 168 /// |
| 169 /// For instance for this hierarchy |
| 170 /// |
| 171 /// class A {} |
| 172 /// class B {} |
| 173 /// class C implements A, B {} |
| 174 /// class D extends C {} |
| 175 /// |
| 176 /// the query |
| 177 /// |
| 178 /// commonSubclasses(A, ClassQuery.SUBTYPE, B, ClassQuery.SUBTYPE) |
| 179 /// |
| 180 /// return the set {C} because [D] is implied by [C]. |
| 181 Iterable<ClassEntity> commonSubclasses(ClassElement cls1, ClassQuery query1, |
| 182 ClassElement cls2, ClassQuery query2); |
| 183 |
| 163 /// Returns an iterable over the live mixin applications that mixin [cls]. | 184 /// Returns an iterable over the live mixin applications that mixin [cls]. |
| 164 Iterable<ClassEntity> mixinUsesOf(ClassEntity cls); | 185 Iterable<ClassEntity> mixinUsesOf(ClassEntity cls); |
| 165 | 186 |
| 166 /// Returns `true` if [cls] is mixed into a live class. | 187 /// Returns `true` if [cls] is mixed into a live class. |
| 167 bool isUsedAsMixin(ClassEntity cls); | 188 bool isUsedAsMixin(ClassEntity cls); |
| 168 | 189 |
| 169 /// Returns `true` if any live class that mixes in [cls] implements [type]. | 190 /// Returns `true` if any live class that mixes in [cls] implements [type]. |
| 170 bool hasAnySubclassOfMixinUseThatImplements( | 191 bool hasAnySubclassOfMixinUseThatImplements( |
| 171 ClassEntity cls, ClassEntity type); | 192 ClassEntity cls, ClassEntity type); |
| 172 | 193 |
| (...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 741 if (link.head.asInstanceOf(cls) == null) { | 762 if (link.head.asInstanceOf(cls) == null) { |
| 742 continue OUTER; | 763 continue OUTER; |
| 743 } | 764 } |
| 744 } | 765 } |
| 745 commonSupertypes.add(cls); | 766 commonSupertypes.add(cls); |
| 746 } | 767 } |
| 747 commonSupertypes.add(commonElements.objectClass); | 768 commonSupertypes.add(commonElements.objectClass); |
| 748 return commonSupertypes; | 769 return commonSupertypes; |
| 749 } | 770 } |
| 750 | 771 |
| 772 Iterable<ClassElement> commonSubclasses(ClassElement cls1, ClassQuery query1, |
| 773 ClassElement cls2, ClassQuery query2) { |
| 774 // TODO(johnniwinther): Use [ClassSet] to compute this. |
| 775 // Compute the set of classes that are contained in both class subsets. |
| 776 Set<ClassEntity> common = |
| 777 _commonContainedClasses(cls1, query1, cls2, query2); |
| 778 if (common == null || common.isEmpty) return const <ClassElement>[]; |
| 779 // Narrow down the candidates by only looking at common classes |
| 780 // that do not have a superclass or supertype that will be a |
| 781 // better candidate. |
| 782 return common.where((ClassElement each) { |
| 783 bool containsSuperclass = common.contains(each.supertype.element); |
| 784 // If the superclass is also a candidate, then we don't want to |
| 785 // deal with this class. If we're only looking for a subclass we |
| 786 // know we don't have to look at the list of interfaces because |
| 787 // they can never be in the common set. |
| 788 if (containsSuperclass || |
| 789 query1 == ClassQuery.SUBCLASS || |
| 790 query2 == ClassQuery.SUBCLASS) { |
| 791 return !containsSuperclass; |
| 792 } |
| 793 // Run through the direct supertypes of the class. If the common |
| 794 // set contains the direct supertype of the class, we ignore the |
| 795 // the class because the supertype is a better candidate. |
| 796 for (Link link = each.interfaces; !link.isEmpty; link = link.tail) { |
| 797 if (common.contains(link.head.element)) return false; |
| 798 } |
| 799 return true; |
| 800 }); |
| 801 } |
| 802 |
| 803 Set<ClassElement> _commonContainedClasses(ClassElement cls1, |
| 804 ClassQuery query1, ClassElement cls2, ClassQuery query2) { |
| 805 Iterable<ClassElement> xSubset = _containedSubset(cls1, query1); |
| 806 if (xSubset == null) return null; |
| 807 Iterable<ClassElement> ySubset = _containedSubset(cls2, query2); |
| 808 if (ySubset == null) return null; |
| 809 return xSubset.toSet().intersection(ySubset.toSet()); |
| 810 } |
| 811 |
| 812 Iterable<ClassElement> _containedSubset(ClassElement cls, ClassQuery query) { |
| 813 switch (query) { |
| 814 case ClassQuery.EXACT: |
| 815 return null; |
| 816 case ClassQuery.SUBCLASS: |
| 817 return strictSubclassesOf(cls); |
| 818 case ClassQuery.SUBTYPE: |
| 819 return strictSubtypesOf(cls); |
| 820 } |
| 821 throw new ArgumentError('Unexpected query: $query.'); |
| 822 } |
| 823 |
| 751 /// Returns an iterable over the live mixin applications that mixin [cls]. | 824 /// Returns an iterable over the live mixin applications that mixin [cls]. |
| 752 Iterable<MixinApplicationElement> mixinUsesOf(ClassElement cls) { | 825 Iterable<MixinApplicationElement> mixinUsesOf(ClassElement cls) { |
| 753 assert(isClosed); | 826 assert(isClosed); |
| 754 if (_liveMixinUses == null) { | 827 if (_liveMixinUses == null) { |
| 755 _liveMixinUses = new Map<ClassElement, List<MixinApplicationElement>>(); | 828 _liveMixinUses = new Map<ClassElement, List<MixinApplicationElement>>(); |
| 756 for (ClassElement mixin in _mixinUses.keys) { | 829 for (ClassElement mixin in _mixinUses.keys) { |
| 757 List<MixinApplicationElement> uses = <MixinApplicationElement>[]; | 830 List<MixinApplicationElement> uses = <MixinApplicationElement>[]; |
| 758 | 831 |
| 759 void addLiveUse(MixinApplicationElement mixinApplication) { | 832 void addLiveUse(MixinApplicationElement mixinApplication) { |
| 760 if (isInstantiated(mixinApplication)) { | 833 if (isInstantiated(mixinApplication)) { |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1111 return getMightBePassedToApply(element.expression); | 1184 return getMightBePassedToApply(element.expression); |
| 1112 } | 1185 } |
| 1113 return functionsThatMightBePassedToApply.contains(element); | 1186 return functionsThatMightBePassedToApply.contains(element); |
| 1114 } | 1187 } |
| 1115 | 1188 |
| 1116 @override | 1189 @override |
| 1117 bool getCurrentlyKnownMightBePassedToApply(Element element) { | 1190 bool getCurrentlyKnownMightBePassedToApply(Element element) { |
| 1118 return getMightBePassedToApply(element); | 1191 return getMightBePassedToApply(element); |
| 1119 } | 1192 } |
| 1120 } | 1193 } |
| OLD | NEW |