| 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 FunctionSet allFunctions; | 9 final FunctionSet allFunctions; |
| 10 final Set<Element> functionsCalledInLoop = new Set<Element>(); | 10 final Set<Element> functionsCalledInLoop = new Set<Element>(); |
| 11 final Map<Element, SideEffects> sideEffects = new Map<Element, SideEffects>(); | 11 final Map<Element, SideEffects> sideEffects = new Map<Element, SideEffects>(); |
| 12 | 12 |
| 13 final Map<ClassElement, Set<MixinApplicationElement>> mixinUses = | 13 final Map<ClassElement, Set<MixinApplicationElement>> mixinUses = |
| 14 new Map<ClassElement, Set<MixinApplicationElement>>(); | 14 new Map<ClassElement, Set<MixinApplicationElement>>(); |
| 15 | 15 |
| 16 final Map<ClassElement, Set<ClassElement>> _typesImplementedBySubclasses = | 16 final Map<ClassElement, Set<ClassElement>> _typesImplementedBySubclasses = |
| 17 new Map<ClassElement, Set<ClassElement>>(); | 17 new Map<ClassElement, Set<ClassElement>>(); |
| 18 | 18 |
| 19 // We keep track of subtype and subclass relationships in four | 19 // We keep track of subtype and subclass relationships in four |
| 20 // distinct sets to make class hierarchy analysis faster. | 20 // distinct sets to make class hierarchy analysis faster. |
| 21 final Map<ClassElement, Set<ClassElement>> _subclasses = | 21 final Map<ClassElement, Set<ClassElement>> _subclasses = |
| 22 new Map<ClassElement, Set<ClassElement>>(); | 22 new Map<ClassElement, Set<ClassElement>>(); |
| 23 final Map<ClassElement, Set<ClassElement>> _superclasses = | |
| 24 new Map<ClassElement, Set<ClassElement>>(); | |
| 25 final Map<ClassElement, Set<ClassElement>> _subtypes = | 23 final Map<ClassElement, Set<ClassElement>> _subtypes = |
| 26 new Map<ClassElement, Set<ClassElement>>(); | 24 new Map<ClassElement, Set<ClassElement>>(); |
| 27 final Map<ClassElement, Set<ClassElement>> _supertypes = | 25 final Map<ClassElement, Set<ClassElement>> _supertypes = |
| 28 new Map<ClassElement, Set<ClassElement>>(); | 26 new Map<ClassElement, Set<ClassElement>>(); |
| 29 | 27 |
| 30 final Set<Element> sideEffectsFreeElements = new Set<Element>(); | 28 final Set<Element> sideEffectsFreeElements = new Set<Element>(); |
| 31 | 29 |
| 32 final Set<Element> elementsThatCannotThrow = new Set<Element>(); | 30 final Set<Element> elementsThatCannotThrow = new Set<Element>(); |
| 33 | 31 |
| 34 Set<ClassElement> subclassesOf(ClassElement cls) { | 32 Set<ClassElement> subclassesOf(ClassElement cls) { |
| 35 return _subclasses[cls.declaration]; | 33 return _subclasses[cls.declaration]; |
| 36 } | 34 } |
| 37 | 35 |
| 38 Set<ClassElement> subtypesOf(ClassElement cls) { | 36 Set<ClassElement> subtypesOf(ClassElement cls) { |
| 39 return _subtypes[cls.declaration]; | 37 return _subtypes[cls.declaration]; |
| 40 } | 38 } |
| 41 | 39 |
| 42 Set<ClassElement> superclassesOf(ClassElement cls) { | |
| 43 return _superclasses[cls.declaration]; | |
| 44 } | |
| 45 | |
| 46 Set<ClassElement> supertypesOf(ClassElement cls) { | 40 Set<ClassElement> supertypesOf(ClassElement cls) { |
| 47 return _supertypes[cls.declaration]; | 41 return _supertypes[cls.declaration]; |
| 48 } | 42 } |
| 49 | 43 |
| 50 Set<ClassElement> typesImplementedBySubclassesOf(ClassElement cls) { | 44 Set<ClassElement> typesImplementedBySubclassesOf(ClassElement cls) { |
| 51 return _typesImplementedBySubclasses[cls.declaration]; | 45 return _typesImplementedBySubclasses[cls.declaration]; |
| 52 } | 46 } |
| 53 | 47 |
| 54 bool hasSubclasses(ClassElement cls) { | 48 bool hasSubclasses(ClassElement cls) { |
| 55 Set<ClassElement> subclasses = compiler.world.subclassesOf(cls); | 49 Set<ClassElement> subclasses = compiler.world.subclassesOf(cls); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 74 Set<Element> subtypesOfSupertype = | 68 Set<Element> subtypesOfSupertype = |
| 75 _subtypes.putIfAbsent(type.element, () => new Set<ClassElement>()); | 69 _subtypes.putIfAbsent(type.element, () => new Set<ClassElement>()); |
| 76 supertypesOfClass.add(type.element); | 70 supertypesOfClass.add(type.element); |
| 77 subtypesOfSupertype.add(cls); | 71 subtypesOfSupertype.add(cls); |
| 78 } | 72 } |
| 79 | 73 |
| 80 // Walk through the superclasses, and record the types | 74 // Walk through the superclasses, and record the types |
| 81 // implemented by that type on the superclasses. | 75 // implemented by that type on the superclasses. |
| 82 DartType type = cls.supertype; | 76 DartType type = cls.supertype; |
| 83 while (type != null) { | 77 while (type != null) { |
| 84 Set<Element> superclassesOfClass = | |
| 85 _superclasses.putIfAbsent(cls, () => new Set<ClassElement>()); | |
| 86 Set<Element> subclassesOfSuperclass = | 78 Set<Element> subclassesOfSuperclass = |
| 87 _subclasses.putIfAbsent(type.element, () => new Set<ClassElement>())
; | 79 _subclasses.putIfAbsent(type.element, () => new Set<ClassElement>())
; |
| 88 superclassesOfClass.add(type.element); | |
| 89 subclassesOfSuperclass.add(cls); | 80 subclassesOfSuperclass.add(cls); |
| 90 | 81 |
| 91 Set<Element> typesImplementedBySubclassesOfCls = | 82 Set<Element> typesImplementedBySubclassesOfCls = |
| 92 _typesImplementedBySubclasses.putIfAbsent( | 83 _typesImplementedBySubclasses.putIfAbsent( |
| 93 type.element, () => new Set<ClassElement>()); | 84 type.element, () => new Set<ClassElement>()); |
| 94 for (DartType current in cls.allSupertypes) { | 85 for (DartType current in cls.allSupertypes) { |
| 95 typesImplementedBySubclassesOfCls.add(current.element); | 86 typesImplementedBySubclassesOfCls.add(current.element); |
| 96 } | 87 } |
| 97 ClassElement classElement = type.element; | 88 ClassElement classElement = type.element; |
| 98 type = classElement.supertype; | 89 type = classElement.supertype; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 | 135 |
| 145 bool hasAnySubtype(ClassElement cls) { | 136 bool hasAnySubtype(ClassElement cls) { |
| 146 Set<ClassElement> classes = subtypesOf(cls); | 137 Set<ClassElement> classes = subtypesOf(cls); |
| 147 return classes != null && !classes.isEmpty; | 138 return classes != null && !classes.isEmpty; |
| 148 } | 139 } |
| 149 | 140 |
| 150 bool hasAnyUserDefinedGetter(Selector selector) { | 141 bool hasAnyUserDefinedGetter(Selector selector) { |
| 151 return allFunctions.filter(selector).any((each) => each.isGetter()); | 142 return allFunctions.filter(selector).any((each) => each.isGetter()); |
| 152 } | 143 } |
| 153 | 144 |
| 154 bool hasAnyUserDefinedSetter(Selector selector) { | |
| 155 return allFunctions.filter(selector).any((each) => each.isSetter()); | |
| 156 } | |
| 157 | |
| 158 // Returns whether a subclass of [superclass] implements [type]. | 145 // Returns whether a subclass of [superclass] implements [type]. |
| 159 bool hasAnySubclassThatImplements(ClassElement superclass, | 146 bool hasAnySubclassThatImplements(ClassElement superclass, |
| 160 ClassElement type) { | 147 ClassElement type) { |
| 161 Set<ClassElement> subclasses = typesImplementedBySubclassesOf(superclass); | 148 Set<ClassElement> subclasses = typesImplementedBySubclassesOf(superclass); |
| 162 if (subclasses == null) return false; | 149 if (subclasses == null) return false; |
| 163 return subclasses.contains(type); | 150 return subclasses.contains(type); |
| 164 } | 151 } |
| 165 | 152 |
| 166 // Returns whether a subclass of any mixin application of [cls] implements | 153 // Returns whether a subclass of any mixin application of [cls] implements |
| 167 // [type]. | 154 // [type]. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 201 return (result != null && result.isField()) ? result : null; | 188 return (result != null && result.isField()) ? result : null; |
| 202 } | 189 } |
| 203 | 190 |
| 204 Element locateSingleElement(Selector selector) { | 191 Element locateSingleElement(Selector selector) { |
| 205 ti.TypeMask mask = selector.mask == null | 192 ti.TypeMask mask = selector.mask == null |
| 206 ? new ti.TypeMask.subclass(compiler.objectClass) | 193 ? new ti.TypeMask.subclass(compiler.objectClass) |
| 207 : selector.mask; | 194 : selector.mask; |
| 208 return mask.locateSingleElement(selector, compiler); | 195 return mask.locateSingleElement(selector, compiler); |
| 209 } | 196 } |
| 210 | 197 |
| 211 bool hasSingleMatch(Selector selector) { | |
| 212 Iterable<Element> targets = allFunctions.filter(selector); | |
| 213 return targets.length == 1; | |
| 214 } | |
| 215 | |
| 216 Iterable<ClassElement> locateNoSuchMethodHolders(Selector selector) { | |
| 217 Selector noSuchMethodSelector = compiler.noSuchMethodSelector; | |
| 218 ti.TypeMask mask = selector.mask; | |
| 219 if (mask != null) { | |
| 220 noSuchMethodSelector = new TypedSelector(mask, noSuchMethodSelector); | |
| 221 } | |
| 222 ClassElement objectClass = compiler.objectClass; | |
| 223 return allFunctions | |
| 224 .filter(noSuchMethodSelector) | |
| 225 .map((Element member) => member.getEnclosingClass()) | |
| 226 .where((ClassElement holder) => !identical(holder, objectClass)); | |
| 227 } | |
| 228 | |
| 229 void addFunctionCalledInLoop(Element element) { | 198 void addFunctionCalledInLoop(Element element) { |
| 230 functionsCalledInLoop.add(element.declaration); | 199 functionsCalledInLoop.add(element.declaration); |
| 231 } | 200 } |
| 232 | 201 |
| 233 bool isCalledInLoop(Element element) { | 202 bool isCalledInLoop(Element element) { |
| 234 return functionsCalledInLoop.contains(element.declaration); | 203 return functionsCalledInLoop.contains(element.declaration); |
| 235 } | 204 } |
| 236 | 205 |
| 237 bool fieldNeverChanges(Element element) { | 206 bool fieldNeverChanges(Element element) { |
| 238 if (!element.isField()) return false; | 207 if (!element.isField()) return false; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 } | 268 } |
| 300 | 269 |
| 301 void registerCannotThrow(Element element) { | 270 void registerCannotThrow(Element element) { |
| 302 elementsThatCannotThrow.add(element); | 271 elementsThatCannotThrow.add(element); |
| 303 } | 272 } |
| 304 | 273 |
| 305 bool getCannotThrow(Element element) { | 274 bool getCannotThrow(Element element) { |
| 306 return elementsThatCannotThrow.contains(element); | 275 return elementsThatCannotThrow.contains(element); |
| 307 } | 276 } |
| 308 } | 277 } |
| OLD | NEW |