| 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 part of dart2js; | 5 part of dart2js; |
| 6 | 6 |
| 7 class World { | 7 class World { |
| 8 final Compiler compiler; | 8 final Compiler compiler; |
| 9 final Map<ClassElement, Set<MixinApplicationElement>> mixinUses; | |
| 10 final Map<ClassElement, Set<ClassElement>> typesImplementedBySubclasses; | |
| 11 final FullFunctionSet allFunctions; | 9 final FullFunctionSet allFunctions; |
| 12 final Set<Element> functionsCalledInLoop = new Set<Element>(); | 10 final Set<Element> functionsCalledInLoop = new Set<Element>(); |
| 13 final Map<Element, SideEffects> sideEffects = new Map<Element, SideEffects>(); | 11 final Map<Element, SideEffects> sideEffects = new Map<Element, SideEffects>(); |
| 14 | 12 |
| 13 final Map<ClassElement, Set<MixinApplicationElement>> mixinUses = |
| 14 new Map<ClassElement, Set<MixinApplicationElement>>(); |
| 15 |
| 16 final Map<ClassElement, Set<ClassElement>> _typesImplementedBySubclasses = |
| 17 new Map<ClassElement, Set<ClassElement>>(); |
| 18 |
| 15 // We keep track of subtype and subclass relationships in four | 19 // We keep track of subtype and subclass relationships in four |
| 16 // distinct sets to make class hierarchy analysis faster. | 20 // distinct sets to make class hierarchy analysis faster. |
| 17 final Map<ClassElement, Set<ClassElement>> subclasses = | 21 final Map<ClassElement, Set<ClassElement>> _subclasses = |
| 18 new Map<ClassElement, Set<ClassElement>>(); | 22 new Map<ClassElement, Set<ClassElement>>(); |
| 19 final Map<ClassElement, Set<ClassElement>> superclasses = | 23 final Map<ClassElement, Set<ClassElement>> _superclasses = |
| 20 new Map<ClassElement, Set<ClassElement>>(); | 24 new Map<ClassElement, Set<ClassElement>>(); |
| 21 final Map<ClassElement, Set<ClassElement>> subtypes = | 25 final Map<ClassElement, Set<ClassElement>> _subtypes = |
| 22 new Map<ClassElement, Set<ClassElement>>(); | 26 new Map<ClassElement, Set<ClassElement>>(); |
| 23 final Map<ClassElement, Set<ClassElement>> supertypes = | 27 final Map<ClassElement, Set<ClassElement>> _supertypes = |
| 24 new Map<ClassElement, Set<ClassElement>>(); | 28 new Map<ClassElement, Set<ClassElement>>(); |
| 25 | 29 |
| 30 Set<ClassElement> subclassesOf(ClassElement cls) { |
| 31 return _subclasses[cls.declaration]; |
| 32 } |
| 33 |
| 34 Set<ClassElement> subtypesOf(ClassElement cls) { |
| 35 return _subtypes[cls.declaration]; |
| 36 } |
| 37 |
| 38 Set<ClassElement> superclassesOf(ClassElement cls) { |
| 39 return _superclasses[cls.declaration]; |
| 40 } |
| 41 |
| 42 Set<ClassElement> supertypesOf(ClassElement cls) { |
| 43 return _supertypes[cls.declaration]; |
| 44 } |
| 45 |
| 46 Set<ClassElement> typesImplementedBySubclassesOf(ClassElement cls) { |
| 47 return _typesImplementedBySubclasses[cls]; |
| 48 } |
| 49 |
| 26 World(Compiler compiler) | 50 World(Compiler compiler) |
| 27 : mixinUses = new Map<ClassElement, Set<MixinApplicationElement>>(), | 51 : allFunctions = new FullFunctionSet(compiler), |
| 28 typesImplementedBySubclasses = | |
| 29 new Map<ClassElement, Set<ClassElement>>(), | |
| 30 allFunctions = new FullFunctionSet(compiler), | |
| 31 this.compiler = compiler; | 52 this.compiler = compiler; |
| 32 | 53 |
| 33 void populate() { | 54 void populate() { |
| 34 void addSubtypes(ClassElement cls) { | 55 void addSubtypes(ClassElement cls) { |
| 56 assert(cls.isDeclaration); |
| 35 if (cls.resolutionState != STATE_DONE) { | 57 if (cls.resolutionState != STATE_DONE) { |
| 36 compiler.internalErrorOnElement( | 58 compiler.internalErrorOnElement( |
| 37 cls, 'Class "${cls.name.slowToString()}" is not resolved.'); | 59 cls, 'Class "${cls.name.slowToString()}" is not resolved.'); |
| 38 } | 60 } |
| 39 | 61 |
| 40 for (DartType type in cls.allSupertypes) { | 62 for (DartType type in cls.allSupertypes) { |
| 41 Set<Element> supertypesOfClass = | 63 Set<Element> supertypesOfClass = |
| 42 supertypes.putIfAbsent(cls, () => new Set<ClassElement>()); | 64 _supertypes.putIfAbsent(cls, () => new Set<ClassElement>()); |
| 43 Set<Element> subtypesOfSupertype = | 65 Set<Element> subtypesOfSupertype = |
| 44 subtypes.putIfAbsent(type.element, () => new Set<ClassElement>()); | 66 _subtypes.putIfAbsent(type.element, () => new Set<ClassElement>()); |
| 45 supertypesOfClass.add(type.element); | 67 supertypesOfClass.add(type.element); |
| 46 subtypesOfSupertype.add(cls); | 68 subtypesOfSupertype.add(cls); |
| 47 } | 69 } |
| 48 | 70 |
| 49 // Walk through the superclasses, and record the types | 71 // Walk through the superclasses, and record the types |
| 50 // implemented by that type on the superclasses. | 72 // implemented by that type on the superclasses. |
| 51 DartType type = cls.supertype; | 73 DartType type = cls.supertype; |
| 52 while (type != null) { | 74 while (type != null) { |
| 53 Set<Element> superclassesOfClass = | 75 Set<Element> superclassesOfClass = |
| 54 superclasses.putIfAbsent(cls, () => new Set<ClassElement>()); | 76 _superclasses.putIfAbsent(cls, () => new Set<ClassElement>()); |
| 55 Set<Element> subclassesOfSuperclass = | 77 Set<Element> subclassesOfSuperclass = |
| 56 subclasses.putIfAbsent(type.element, () => new Set<ClassElement>()); | 78 _subclasses.putIfAbsent(type.element, () => new Set<ClassElement>())
; |
| 57 superclassesOfClass.add(type.element); | 79 superclassesOfClass.add(type.element); |
| 58 subclassesOfSuperclass.add(cls); | 80 subclassesOfSuperclass.add(cls); |
| 59 | 81 |
| 60 Set<Element> typesImplementedBySubclassesOfCls = | 82 Set<Element> typesImplementedBySubclassesOfCls = |
| 61 typesImplementedBySubclasses.putIfAbsent( | 83 _typesImplementedBySubclasses.putIfAbsent( |
| 62 type.element, () => new Set<ClassElement>()); | 84 type.element, () => new Set<ClassElement>()); |
| 63 for (DartType current in cls.allSupertypes) { | 85 for (DartType current in cls.allSupertypes) { |
| 64 typesImplementedBySubclassesOfCls.add(current.element); | 86 typesImplementedBySubclassesOfCls.add(current.element); |
| 65 } | 87 } |
| 66 ClassElement classElement = type.element; | 88 ClassElement classElement = type.element; |
| 67 type = classElement.supertype; | 89 type = classElement.supertype; |
| 68 } | 90 } |
| 69 } | 91 } |
| 70 | 92 |
| 71 // Use the [:seenClasses:] set to include non-instantiated | 93 // Use the [:seenClasses:] set to include non-instantiated |
| 72 // classes: if the superclass of these classes require RTI, then | 94 // classes: if the superclass of these classes require RTI, then |
| 73 // they also need RTI, so that a constructor passes the type | 95 // they also need RTI, so that a constructor passes the type |
| 74 // variables to the super constructor. | 96 // variables to the super constructor. |
| 75 compiler.enqueuer.resolution.seenClasses.forEach(addSubtypes); | 97 compiler.enqueuer.resolution.seenClasses.forEach(addSubtypes); |
| 76 } | 98 } |
| 77 | 99 |
| 78 Iterable<ClassElement> commonSupertypesOf(ClassElement x, ClassElement y) { | 100 Iterable<ClassElement> commonSupertypesOf(ClassElement x, ClassElement y) { |
| 79 Set<ClassElement> xSet = supertypes[x]; | 101 Set<ClassElement> xSet = supertypesOf(x); |
| 80 if (xSet == null) return const <ClassElement>[]; | 102 if (xSet == null) return const <ClassElement>[]; |
| 81 Set<ClassElement> ySet = supertypes[y]; | 103 Set<ClassElement> ySet = supertypesOf(y); |
| 82 if (ySet == null) return const <ClassElement>[]; | 104 if (ySet == null) return const <ClassElement>[]; |
| 83 Set<ClassElement> smallSet, largeSet; | 105 Set<ClassElement> smallSet, largeSet; |
| 84 if (xSet.length <= ySet.length) { | 106 if (xSet.length <= ySet.length) { |
| 85 smallSet = xSet; | 107 smallSet = xSet; |
| 86 largeSet = ySet; | 108 largeSet = ySet; |
| 87 } else { | 109 } else { |
| 88 smallSet = ySet; | 110 smallSet = ySet; |
| 89 largeSet = xSet; | 111 largeSet = xSet; |
| 90 } | 112 } |
| 91 return smallSet.where((ClassElement each) => largeSet.contains(each)); | 113 return smallSet.where((ClassElement each) => largeSet.contains(each)); |
| 92 } | 114 } |
| 93 | 115 |
| 94 void registerMixinUse(MixinApplicationElement mixinApplication, | 116 void registerMixinUse(MixinApplicationElement mixinApplication, |
| 95 ClassElement mixin) { | 117 ClassElement mixin) { |
| 118 // We don't support patch classes as mixin. |
| 119 assert(mixin.isDeclaration); |
| 96 Set<MixinApplicationElement> users = | 120 Set<MixinApplicationElement> users = |
| 97 mixinUses.putIfAbsent(mixin, () => | 121 mixinUses.putIfAbsent(mixin, () => |
| 98 new Set<MixinApplicationElement>()); | 122 new Set<MixinApplicationElement>()); |
| 99 users.add(mixinApplication); | 123 users.add(mixinApplication); |
| 100 } | 124 } |
| 101 | 125 |
| 102 bool isUsedAsMixin(ClassElement cls) { | 126 bool isUsedAsMixin(ClassElement cls) { |
| 103 Set<MixinApplicationElement> uses = mixinUses[cls]; | 127 Set<MixinApplicationElement> uses = mixinUses[cls]; |
| 104 return uses != null && !uses.isEmpty; | 128 return uses != null && !uses.isEmpty; |
| 105 } | 129 } |
| 106 | 130 |
| 107 bool hasAnySubclass(ClassElement cls) { | 131 bool hasAnySubclass(ClassElement cls) { |
| 108 Set<ClassElement> classes = subclasses[cls]; | 132 Set<ClassElement> classes = subclassesOf(cls); |
| 109 return classes != null && !classes.isEmpty; | 133 return classes != null && !classes.isEmpty; |
| 110 } | 134 } |
| 111 | 135 |
| 112 bool hasAnySubtype(ClassElement cls) { | 136 bool hasAnySubtype(ClassElement cls) { |
| 113 Set<ClassElement> classes = subtypes[cls]; | 137 Set<ClassElement> classes = subtypesOf(cls); |
| 114 return classes != null && !classes.isEmpty; | 138 return classes != null && !classes.isEmpty; |
| 115 } | 139 } |
| 116 | 140 |
| 117 bool hasAnyUserDefinedGetter(Selector selector) { | 141 bool hasAnyUserDefinedGetter(Selector selector) { |
| 118 return allFunctions.filter(selector).any((each) => each.isGetter()); | 142 return allFunctions.filter(selector).any((each) => each.isGetter()); |
| 119 } | 143 } |
| 120 | 144 |
| 121 bool hasAnyUserDefinedSetter(Selector selector) { | 145 bool hasAnyUserDefinedSetter(Selector selector) { |
| 122 return allFunctions.filter(selector).any((each) => each.isSetter()); | 146 return allFunctions.filter(selector).any((each) => each.isSetter()); |
| 123 } | 147 } |
| 124 | 148 |
| 125 // Returns whether a subclass of [superclass] implements [type]. | 149 // Returns whether a subclass of [superclass] implements [type]. |
| 126 bool hasAnySubclassThatImplements(ClassElement superclass, DartType type) { | 150 bool hasAnySubclassThatImplements(ClassElement superclass, DartType type) { |
| 127 Set<ClassElement> subclasses = typesImplementedBySubclasses[superclass]; | 151 Set<ClassElement> subclasses = typesImplementedBySubclassesOf(superclass); |
| 128 if (subclasses == null) return false; | 152 if (subclasses == null) return false; |
| 129 return subclasses.contains(type.element); | 153 return subclasses.contains(type.element); |
| 130 } | 154 } |
| 131 | 155 |
| 132 // Returns whether a subclass of [superclass] mixes in [other]. | 156 // Returns whether a subclass of [superclass] mixes in [other]. |
| 133 bool hasAnySubclassThatMixes(ClassElement superclass, ClassElement other) { | 157 bool hasAnySubclassThatMixes(ClassElement superclass, ClassElement other) { |
| 134 Set<MixinApplicationElement> uses = mixinUses[other]; | 158 Set<MixinApplicationElement> uses = mixinUses[other]; |
| 135 return (uses != null) | 159 return (uses != null) |
| 136 ? uses.any((each) => each.isSubclassOf(superclass)) | 160 ? uses.any((each) => each.isSubclassOf(superclass)) |
| 137 : false; | 161 : false; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 sideEffects.setDependsOnInstancePropertyStore(); | 227 sideEffects.setDependsOnInstancePropertyStore(); |
| 204 } else if (selector.isSetter()) { | 228 } else if (selector.isSetter()) { |
| 205 sideEffects.setChangesInstanceProperty(); | 229 sideEffects.setChangesInstanceProperty(); |
| 206 } | 230 } |
| 207 } | 231 } |
| 208 sideEffects.add(getSideEffectsOfElement(e)); | 232 sideEffects.add(getSideEffectsOfElement(e)); |
| 209 } | 233 } |
| 210 return sideEffects; | 234 return sideEffects; |
| 211 } | 235 } |
| 212 } | 236 } |
| OLD | NEW |