| 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'; |
| 11 import 'core_types.dart' show CommonElements; | 11 import 'core_types.dart' show CommonElements; |
| 12 import 'elements/resolution_types.dart'; | 12 import 'elements/entities.dart'; |
| 13 import 'elements/elements.dart' | 13 import 'elements/elements.dart' |
| 14 show | 14 show |
| 15 ClassElement, | 15 ClassElement, |
| 16 Element, | 16 Element, |
| 17 Entity, |
| 17 FunctionElement, | 18 FunctionElement, |
| 18 MemberElement, | 19 MemberElement, |
| 19 MixinApplicationElement, | 20 MixinApplicationElement, |
| 20 TypedefElement, | 21 TypedefElement, |
| 21 FieldElement; | 22 FieldElement; |
| 23 import 'elements/resolution_types.dart'; |
| 22 import 'js_backend/backend.dart' show JavaScriptBackend; | 24 import 'js_backend/backend.dart' show JavaScriptBackend; |
| 23 import 'ordered_typeset.dart'; | 25 import 'ordered_typeset.dart'; |
| 24 import 'types/masks.dart' show CommonMasks, FlatTypeMask, TypeMask; | 26 import 'types/masks.dart' show CommonMasks, FlatTypeMask, TypeMask; |
| 25 import 'universe/class_set.dart'; | 27 import 'universe/class_set.dart'; |
| 26 import 'universe/function_set.dart' show FunctionSet, FunctionSetBuilder; | 28 import 'universe/function_set.dart' show FunctionSet, FunctionSetBuilder; |
| 27 import 'universe/selector.dart' show Selector; | 29 import 'universe/selector.dart' show Selector; |
| 28 import 'universe/side_effects.dart' show SideEffects; | 30 import 'universe/side_effects.dart' show SideEffects; |
| 29 import 'universe/world_builder.dart' show ResolutionWorldBuilder; | 31 import 'universe/world_builder.dart' show ResolutionWorldBuilder; |
| 30 import 'util/util.dart' show Link; | 32 import 'util/util.dart' show Link; |
| 31 | 33 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 44 /// Access to core classes used by the backend. | 46 /// Access to core classes used by the backend. |
| 45 BackendClasses get backendClasses; | 47 BackendClasses get backendClasses; |
| 46 | 48 |
| 47 CommonElements get commonElements; | 49 CommonElements get commonElements; |
| 48 | 50 |
| 49 CommonMasks get commonMasks; | 51 CommonMasks get commonMasks; |
| 50 | 52 |
| 51 ConstantSystem get constantSystem; | 53 ConstantSystem get constantSystem; |
| 52 | 54 |
| 53 /// Returns `true` if [cls] is either directly or indirectly instantiated. | 55 /// Returns `true` if [cls] is either directly or indirectly instantiated. |
| 54 bool isInstantiated(ClassElement cls); | 56 bool isInstantiated(ClassEntity cls); |
| 55 | 57 |
| 56 /// Returns `true` if [cls] is directly instantiated. This means that at | 58 /// Returns `true` if [cls] is directly instantiated. This means that at |
| 57 /// runtime instances of exactly [cls] are assumed to exist. | 59 /// runtime instances of exactly [cls] are assumed to exist. |
| 58 bool isDirectlyInstantiated(ClassElement cls); | 60 bool isDirectlyInstantiated(ClassEntity cls); |
| 59 | 61 |
| 60 /// Returns `true` if [cls] is abstractly instantiated. This means that at | 62 /// Returns `true` if [cls] is abstractly instantiated. This means that at |
| 61 /// runtime instances of [cls] or unknown subclasses of [cls] are assumed to | 63 /// runtime instances of [cls] or unknown subclasses of [cls] are assumed to |
| 62 /// exist. | 64 /// exist. |
| 63 /// | 65 /// |
| 64 /// This is used to mark native and/or reflectable classes as instantiated. | 66 /// This is used to mark native and/or reflectable classes as instantiated. |
| 65 /// For native classes we do not know the exact class that instantiates [cls] | 67 /// For native classes we do not know the exact class that instantiates [cls] |
| 66 /// so [cls] here represents the root of the subclasses. For reflectable | 68 /// so [cls] here represents the root of the subclasses. For reflectable |
| 67 /// classes we need event abstract classes to be 'live' even though they | 69 /// classes we need event abstract classes to be 'live' even though they |
| 68 /// cannot themselves be instantiated. | 70 /// cannot themselves be instantiated. |
| 69 bool isAbstractlyInstantiated(ClassElement cls); | 71 bool isAbstractlyInstantiated(ClassEntity cls); |
| 70 | 72 |
| 71 /// Returns `true` if [cls] is either directly or abstractly instantiated. | 73 /// Returns `true` if [cls] is either directly or abstractly instantiated. |
| 72 /// | 74 /// |
| 73 /// See [isDirectlyInstantiated] and [isAbstractlyInstantiated]. | 75 /// See [isDirectlyInstantiated] and [isAbstractlyInstantiated]. |
| 74 bool isExplicitlyInstantiated(ClassElement cls); | 76 bool isExplicitlyInstantiated(ClassEntity cls); |
| 75 | 77 |
| 76 /// Returns `true` if [cls] is indirectly instantiated, that is through a | 78 /// Returns `true` if [cls] is indirectly instantiated, that is through a |
| 77 /// subclass. | 79 /// subclass. |
| 78 bool isIndirectlyInstantiated(ClassElement cls); | 80 bool isIndirectlyInstantiated(ClassEntity cls); |
| 79 | 81 |
| 80 /// Returns `true` if [cls] is abstract and thus can only be instantiated | 82 /// Returns `true` if [cls] is abstract and thus can only be instantiated |
| 81 /// through subclasses. | 83 /// through subclasses. |
| 82 bool isAbstract(ClassElement cls); | 84 bool isAbstract(ClassEntity cls); |
| 83 | 85 |
| 84 /// Returns `true` if [cls] is implemented by an instantiated class. | 86 /// Returns `true` if [cls] is implemented by an instantiated class. |
| 85 bool isImplemented(ClassElement cls); | 87 bool isImplemented(ClassEntity cls); |
| 86 | 88 |
| 87 /// Return `true` if [x] is a subclass of [y]. | 89 /// Return `true` if [x] is a subclass of [y]. |
| 88 bool isSubclassOf(ClassElement x, ClassElement y); | 90 bool isSubclassOf(ClassEntity x, ClassEntity y); |
| 89 | 91 |
| 90 /// Returns `true` if [x] is a subtype of [y], that is, if [x] implements an | 92 /// Returns `true` if [x] is a subtype of [y], that is, if [x] implements an |
| 91 /// instance of [y]. | 93 /// instance of [y]. |
| 92 bool isSubtypeOf(ClassElement x, ClassElement y); | 94 bool isSubtypeOf(ClassEntity x, ClassEntity y); |
| 93 | 95 |
| 94 /// Returns an iterable over the live classes that extend [cls] including | 96 /// Returns an iterable over the live classes that extend [cls] including |
| 95 /// [cls] itself. | 97 /// [cls] itself. |
| 96 Iterable<ClassElement> subclassesOf(ClassElement cls); | 98 Iterable<ClassEntity> subclassesOf(ClassEntity cls); |
| 97 | 99 |
| 98 /// Returns an iterable over the live classes that extend [cls] _not_ | 100 /// Returns an iterable over the live classes that extend [cls] _not_ |
| 99 /// including [cls] itself. | 101 /// including [cls] itself. |
| 100 Iterable<ClassElement> strictSubclassesOf(ClassElement cls); | 102 Iterable<ClassEntity> strictSubclassesOf(ClassEntity cls); |
| 101 | 103 |
| 102 /// Returns the number of live classes that extend [cls] _not_ | 104 /// Returns the number of live classes that extend [cls] _not_ |
| 103 /// including [cls] itself. | 105 /// including [cls] itself. |
| 104 int strictSubclassCount(ClassElement cls); | 106 int strictSubclassCount(ClassEntity cls); |
| 105 | 107 |
| 106 /// Applies [f] to each live class that extend [cls] _not_ including [cls] | 108 /// Applies [f] to each live class that extend [cls] _not_ including [cls] |
| 107 /// itself. | 109 /// itself. |
| 108 void forEachStrictSubclassOf( | 110 void forEachStrictSubclassOf( |
| 109 ClassElement cls, IterationStep f(ClassElement cls)); | 111 ClassEntity cls, IterationStep f(ClassEntity cls)); |
| 110 | 112 |
| 111 /// Returns `true` if [predicate] applies to any live class that extend [cls] | 113 /// Returns `true` if [predicate] applies to any live class that extend [cls] |
| 112 /// _not_ including [cls] itself. | 114 /// _not_ including [cls] itself. |
| 113 bool anyStrictSubclassOf(ClassElement cls, bool predicate(ClassElement cls)); | 115 bool anyStrictSubclassOf(ClassEntity cls, bool predicate(ClassEntity cls)); |
| 114 | 116 |
| 115 /// Returns an iterable over the directly instantiated that implement [cls] | 117 /// Returns an iterable over the directly instantiated that implement [cls] |
| 116 /// possibly including [cls] itself, if it is live. | 118 /// possibly including [cls] itself, if it is live. |
| 117 Iterable<ClassElement> subtypesOf(ClassElement cls); | 119 Iterable<ClassElement> subtypesOf(ClassEntity cls); |
| 118 | 120 |
| 119 /// Returns an iterable over the live classes that implement [cls] _not_ | 121 /// Returns an iterable over the live classes that implement [cls] _not_ |
| 120 /// including [cls] if it is live. | 122 /// including [cls] if it is live. |
| 121 Iterable<ClassElement> strictSubtypesOf(ClassElement cls); | 123 Iterable<ClassElement> strictSubtypesOf(ClassEntity cls); |
| 122 | 124 |
| 123 /// Returns the number of live classes that implement [cls] _not_ | 125 /// Returns the number of live classes that implement [cls] _not_ |
| 124 /// including [cls] itself. | 126 /// including [cls] itself. |
| 125 int strictSubtypeCount(ClassElement cls); | 127 int strictSubtypeCount(ClassEntity cls); |
| 126 | 128 |
| 127 /// Applies [f] to each live class that implements [cls] _not_ including [cls] | 129 /// Applies [f] to each live class that implements [cls] _not_ including [cls] |
| 128 /// itself. | 130 /// itself. |
| 129 void forEachStrictSubtypeOf( | 131 void forEachStrictSubtypeOf( |
| 130 ClassElement cls, IterationStep f(ClassElement cls)); | 132 ClassEntity cls, IterationStep f(ClassEntity cls)); |
| 131 | 133 |
| 132 /// Returns `true` if [predicate] applies to any live class that implements | 134 /// Returns `true` if [predicate] applies to any live class that implements |
| 133 /// [cls] _not_ including [cls] itself. | 135 /// [cls] _not_ including [cls] itself. |
| 134 bool anyStrictSubtypeOf(ClassElement cls, bool predicate(ClassElement cls)); | 136 bool anyStrictSubtypeOf(ClassEntity cls, bool predicate(ClassEntity cls)); |
| 135 | 137 |
| 136 /// Returns `true` if [a] and [b] have any known common subtypes. | 138 /// Returns `true` if [a] and [b] have any known common subtypes. |
| 137 bool haveAnyCommonSubtypes(ClassElement a, ClassElement b); | 139 bool haveAnyCommonSubtypes(ClassEntity a, ClassEntity b); |
| 138 | 140 |
| 139 /// Returns `true` if any live class other than [cls] extends [cls]. | 141 /// Returns `true` if any live class other than [cls] extends [cls]. |
| 140 bool hasAnyStrictSubclass(ClassElement cls); | 142 bool hasAnyStrictSubclass(ClassEntity cls); |
| 141 | 143 |
| 142 /// Returns `true` if any live class other than [cls] implements [cls]. | 144 /// Returns `true` if any live class other than [cls] implements [cls]. |
| 143 bool hasAnyStrictSubtype(ClassElement cls); | 145 bool hasAnyStrictSubtype(ClassEntity cls); |
| 144 | 146 |
| 145 /// Returns `true` if all live classes that implement [cls] extend it. | 147 /// Returns `true` if all live classes that implement [cls] extend it. |
| 146 bool hasOnlySubclasses(ClassElement cls); | 148 bool hasOnlySubclasses(ClassEntity cls); |
| 147 | 149 |
| 148 /// Returns the most specific subclass of [cls] (including [cls]) that is | 150 /// Returns the most specific subclass of [cls] (including [cls]) that is |
| 149 /// directly instantiated or a superclass of all directly instantiated | 151 /// directly instantiated or a superclass of all directly instantiated |
| 150 /// subclasses. If [cls] is not instantiated, `null` is returned. | 152 /// subclasses. If [cls] is not instantiated, `null` is returned. |
| 151 ClassElement getLubOfInstantiatedSubclasses(ClassElement cls); | 153 ClassEntity getLubOfInstantiatedSubclasses(ClassEntity cls); |
| 152 | 154 |
| 153 /// Returns the most specific subtype of [cls] (including [cls]) that is | 155 /// Returns the most specific subtype of [cls] (including [cls]) that is |
| 154 /// directly instantiated or a superclass of all directly instantiated | 156 /// directly instantiated or a superclass of all directly instantiated |
| 155 /// subtypes. If no subtypes of [cls] are instantiated, `null` is returned. | 157 /// subtypes. If no subtypes of [cls] are instantiated, `null` is returned. |
| 156 ClassElement getLubOfInstantiatedSubtypes(ClassElement cls); | 158 ClassEntity getLubOfInstantiatedSubtypes(ClassEntity cls); |
| 157 | 159 |
| 158 /// Returns an iterable over the common supertypes of the [classes]. | 160 /// Returns an iterable over the common supertypes of the [classes]. |
| 159 Iterable<ClassElement> commonSupertypesOf(Iterable<ClassElement> classes); | 161 Iterable<ClassEntity> commonSupertypesOf(Iterable<ClassEntity> classes); |
| 160 | 162 |
| 161 /// Returns an iterable over the live mixin applications that mixin [cls]. | 163 /// Returns an iterable over the live mixin applications that mixin [cls]. |
| 162 Iterable<MixinApplicationElement> mixinUsesOf(ClassElement cls); | 164 Iterable<ClassEntity> mixinUsesOf(ClassEntity cls); |
| 163 | 165 |
| 164 /// Returns `true` if [cls] is mixed into a live class. | 166 /// Returns `true` if [cls] is mixed into a live class. |
| 165 bool isUsedAsMixin(ClassElement cls); | 167 bool isUsedAsMixin(ClassEntity cls); |
| 166 | 168 |
| 167 /// Returns `true` if any live class that mixes in [cls] implements [type]. | 169 /// Returns `true` if any live class that mixes in [cls] implements [type]. |
| 168 bool hasAnySubclassOfMixinUseThatImplements( | 170 bool hasAnySubclassOfMixinUseThatImplements( |
| 169 ClassElement cls, ClassElement type); | 171 ClassEntity cls, ClassEntity type); |
| 170 | 172 |
| 171 /// Returns `true` if any live class that mixes in [mixin] is also a subclass | 173 /// Returns `true` if any live class that mixes in [mixin] is also a subclass |
| 172 /// of [superclass]. | 174 /// of [superclass]. |
| 173 bool hasAnySubclassThatMixes(ClassElement superclass, ClassElement mixin); | 175 bool hasAnySubclassThatMixes(ClassEntity superclass, ClassEntity mixin); |
| 174 | 176 |
| 175 /// Returns `true` if [cls] or any superclass mixes in [mixin]. | 177 /// Returns `true` if [cls] or any superclass mixes in [mixin]. |
| 176 bool isSubclassOfMixinUseOf(ClassElement cls, ClassElement mixin); | 178 bool isSubclassOfMixinUseOf(ClassEntity cls, ClassEntity mixin); |
| 177 | 179 |
| 178 /// Returns `true` if every subtype of [x] is a subclass of [y] or a subclass | 180 /// Returns `true` if every subtype of [x] is a subclass of [y] or a subclass |
| 179 /// of a mixin application of [y]. | 181 /// of a mixin application of [y]. |
| 180 bool everySubtypeIsSubclassOfOrMixinUseOf(ClassElement x, ClassElement y); | 182 bool everySubtypeIsSubclassOfOrMixinUseOf(ClassEntity x, ClassEntity y); |
| 181 | 183 |
| 182 /// Returns `true` if any subclass of [superclass] implements [type]. | 184 /// Returns `true` if any subclass of [superclass] implements [type]. |
| 183 bool hasAnySubclassThatImplements(ClassElement superclass, ClassElement type); | 185 bool hasAnySubclassThatImplements(ClassEntity superclass, ClassEntity type); |
| 184 | 186 |
| 185 /// Returns `true` if a call of [selector] on [cls] and/or subclasses/subtypes | 187 /// Returns `true` if a call of [selector] on [cls] and/or subclasses/subtypes |
| 186 /// need noSuchMethod handling. | 188 /// need noSuchMethod handling. |
| 187 /// | 189 /// |
| 188 /// If the receiver is guaranteed to have a member that matches what we're | 190 /// If the receiver is guaranteed to have a member that matches what we're |
| 189 /// looking for, there's no need to introduce a noSuchMethod handler. It will | 191 /// looking for, there's no need to introduce a noSuchMethod handler. It will |
| 190 /// never be called. | 192 /// never be called. |
| 191 /// | 193 /// |
| 192 /// As an example, consider this class hierarchy: | 194 /// As an example, consider this class hierarchy: |
| 193 /// | 195 /// |
| (...skipping 20 matching lines...) Expand all Loading... |
| 214 /// | 216 /// |
| 215 /// When calling foo on an object of type A, we know that the implementations | 217 /// When calling foo on an object of type A, we know that the implementations |
| 216 /// of noSuchMethod are in the classes B and D that also (indirectly) | 218 /// of noSuchMethod are in the classes B and D that also (indirectly) |
| 217 /// implement foo, so we do not need a handler for it. | 219 /// implement foo, so we do not need a handler for it. |
| 218 /// | 220 /// |
| 219 /// If we're calling bar on an object of type D, we don't need the handler | 221 /// If we're calling bar on an object of type D, we don't need the handler |
| 220 /// either because all objects of type D implement bar through inheritance. | 222 /// either because all objects of type D implement bar through inheritance. |
| 221 /// | 223 /// |
| 222 /// If we're calling bar on an object of type A we do need the handler because | 224 /// If we're calling bar on an object of type A we do need the handler because |
| 223 /// we may have to call B.noSuchMethod since B does not implement bar. | 225 /// we may have to call B.noSuchMethod since B does not implement bar. |
| 224 bool needsNoSuchMethod(ClassElement cls, Selector selector, ClassQuery query); | 226 bool needsNoSuchMethod(ClassEntity cls, Selector selector, ClassQuery query); |
| 225 | 227 |
| 226 /// Returns whether [element] will be the one used at runtime when being | 228 /// Returns whether [element] will be the one used at runtime when being |
| 227 /// invoked on an instance of [cls]. [selector] is used to ensure library | 229 /// invoked on an instance of [cls]. [selector] is used to ensure library |
| 228 /// privacy is taken into account. | 230 /// privacy is taken into account. |
| 229 bool hasElementIn(ClassElement cls, Selector selector, Element element); | 231 bool hasElementIn(ClassEntity cls, Selector selector, Entity element); |
| 230 | 232 |
| 231 /// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies | 233 /// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies |
| 232 /// of known classes. | 234 /// of known classes. |
| 233 /// | 235 /// |
| 234 /// This method is only provided for testing. For queries on classes, use the | 236 /// This method is only provided for testing. For queries on classes, use the |
| 235 /// methods defined in [ClosedWorld]. | 237 /// methods defined in [ClosedWorld]. |
| 236 ClassHierarchyNode getClassHierarchyNode(ClassElement cls); | 238 ClassHierarchyNode getClassHierarchyNode(ClassEntity cls); |
| 237 | 239 |
| 238 /// Returns [ClassSet] for [cls] used to model the extends and implements | 240 /// Returns [ClassSet] for [cls] used to model the extends and implements |
| 239 /// relations of known classes. | 241 /// relations of known classes. |
| 240 /// | 242 /// |
| 241 /// This method is only provided for testing. For queries on classes, use the | 243 /// This method is only provided for testing. For queries on classes, use the |
| 242 /// methods defined in [ClosedWorld]. | 244 /// methods defined in [ClosedWorld]. |
| 243 ClassSet getClassSet(ClassElement cls); | 245 ClassSet getClassSet(ClassEntity cls); |
| 244 | 246 |
| 245 /// Return the cached mask for [base] with the given flags, or | 247 /// Return the cached mask for [base] with the given flags, or |
| 246 /// calls [createMask] to create the mask and cache it. | 248 /// calls [createMask] to create the mask and cache it. |
| 247 // TODO(johnniwinther): Find a better strategy for caching these? | 249 // TODO(johnniwinther): Find a better strategy for caching these? |
| 248 TypeMask getCachedMask(ClassElement base, int flags, TypeMask createMask()); | 250 TypeMask getCachedMask(ClassEntity base, int flags, TypeMask createMask()); |
| 249 | 251 |
| 250 /// Returns the [FunctionSet] containing all live functions in the closed | 252 /// Returns the [FunctionSet] containing all live functions in the closed |
| 251 /// world. | 253 /// world. |
| 252 FunctionSet get allFunctions; | 254 FunctionSet get allFunctions; |
| 253 | 255 |
| 254 /// Returns `true` if the field [element] is known to be effectively final. | 256 /// Returns `true` if the field [element] is known to be effectively final. |
| 255 bool fieldNeverChanges(MemberElement element); | 257 bool fieldNeverChanges(MemberEntity element); |
| 256 | 258 |
| 257 /// Extends the receiver type [mask] for calling [selector] to take live | 259 /// Extends the receiver type [mask] for calling [selector] to take live |
| 258 /// `noSuchMethod` handlers into account. | 260 /// `noSuchMethod` handlers into account. |
| 259 TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask); | 261 TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask); |
| 260 | 262 |
| 261 /// Returns all resolved typedefs. | 263 /// Returns all resolved typedefs. |
| 262 Iterable<TypedefElement> get allTypedefs; | 264 Iterable<TypedefElement> get allTypedefs; |
| 263 | 265 |
| 264 /// Returns the single [Element] that matches a call to [selector] on a | 266 /// Returns the single [Element] that matches a call to [selector] on a |
| 265 /// receiver of type [mask]. If multiple targets exist, `null` is returned. | 267 /// receiver of type [mask]. If multiple targets exist, `null` is returned. |
| 266 MemberElement locateSingleElement(Selector selector, TypeMask mask); | 268 MemberEntity locateSingleElement(Selector selector, TypeMask mask); |
| 267 | 269 |
| 268 /// Returns the single field that matches a call to [selector] on a | 270 /// Returns the single field that matches a call to [selector] on a |
| 269 /// receiver of type [mask]. If multiple targets exist or the single target | 271 /// receiver of type [mask]. If multiple targets exist or the single target |
| 270 /// is not a field, `null` is returned. | 272 /// is not a field, `null` is returned. |
| 271 FieldElement locateSingleField(Selector selector, TypeMask mask); | 273 FieldEntity locateSingleField(Selector selector, TypeMask mask); |
| 272 | 274 |
| 273 /// Returns the side effects of executing [element]. | 275 /// Returns the side effects of executing [element]. |
| 274 SideEffects getSideEffectsOfElement(Element element); | 276 SideEffects getSideEffectsOfElement(Element element); |
| 275 | 277 |
| 276 /// Returns the side effects of calling [selector] on a receiver of type | 278 /// Returns the side effects of calling [selector] on a receiver of type |
| 277 /// [mask]. | 279 /// [mask]. |
| 278 SideEffects getSideEffectsOfSelector(Selector selector, TypeMask mask); | 280 SideEffects getSideEffectsOfSelector(Selector selector, TypeMask mask); |
| 279 | 281 |
| 280 /// Returns `true` if [element] is guaranteed not to throw an exception. | 282 /// Returns `true` if [element] is guaranteed not to throw an exception. |
| 281 bool getCannotThrow(Element element); | 283 bool getCannotThrow(Element element); |
| 282 | 284 |
| 283 /// Returns `true` if [element] is called in a loop. | 285 /// Returns `true` if [element] is called in a loop. |
| 284 // TODO(johnniwinther): Is this 'potentially called' or 'known to be called'? | 286 // TODO(johnniwinther): Is this 'potentially called' or 'known to be called'? |
| 285 bool isCalledInLoop(Element element); | 287 bool isCalledInLoop(Element element); |
| 286 | 288 |
| 287 /// Returns `true` if [element] might be passed to `Function.apply`. | 289 /// Returns `true` if [element] might be passed to `Function.apply`. |
| 288 // TODO(johnniwinther): Is this 'passed invocation target` or | 290 // TODO(johnniwinther): Is this 'passed invocation target` or |
| 289 // `passed as argument`? | 291 // `passed as argument`? |
| 290 bool getMightBePassedToApply(Element element); | 292 bool getMightBePassedToApply(Element element); |
| 291 | 293 |
| 292 /// Returns a string representation of the closed world. | 294 /// Returns a string representation of the closed world. |
| 293 /// | 295 /// |
| 294 /// If [cls] is provided, the dump will contain only classes related to [cls]. | 296 /// If [cls] is provided, the dump will contain only classes related to [cls]. |
| 295 String dump([ClassElement cls]); | 297 String dump([ClassEntity cls]); |
| 296 } | 298 } |
| 297 | 299 |
| 298 /// Interface for computing side effects and uses of elements. This is used | 300 /// Interface for computing side effects and uses of elements. This is used |
| 299 /// during type inference to compute the [ClosedWorld] for code generation. | 301 /// during type inference to compute the [ClosedWorld] for code generation. |
| 300 abstract class ClosedWorldRefiner { | 302 abstract class ClosedWorldRefiner { |
| 301 /// The closed world being refined. | 303 /// The closed world being refined. |
| 302 ClosedWorld get closedWorld; | 304 ClosedWorld get closedWorld; |
| 303 | 305 |
| 304 /// Registers the side [effects] of executing [element]. | 306 /// Registers the side [effects] of executing [element]. |
| 305 void registerSideEffects(Element element, SideEffects effects); | 307 void registerSideEffects(Element element, SideEffects effects); |
| (...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 982 | 984 |
| 983 bool hasAnyUserDefinedGetter(Selector selector, TypeMask mask) { | 985 bool hasAnyUserDefinedGetter(Selector selector, TypeMask mask) { |
| 984 return allFunctions.filter(selector, mask).any((each) => each.isGetter); | 986 return allFunctions.filter(selector, mask).any((each) => each.isGetter); |
| 985 } | 987 } |
| 986 | 988 |
| 987 FieldElement locateSingleField(Selector selector, TypeMask mask) { | 989 FieldElement locateSingleField(Selector selector, TypeMask mask) { |
| 988 Element result = locateSingleElement(selector, mask); | 990 Element result = locateSingleElement(selector, mask); |
| 989 return (result != null && result.isField) ? result : null; | 991 return (result != null && result.isField) ? result : null; |
| 990 } | 992 } |
| 991 | 993 |
| 992 Element locateSingleElement(Selector selector, TypeMask mask) { | 994 MemberElement locateSingleElement(Selector selector, TypeMask mask) { |
| 993 assert(isClosed); | 995 assert(isClosed); |
| 994 mask ??= commonMasks.dynamicType; | 996 mask ??= commonMasks.dynamicType; |
| 995 return mask.locateSingleElement(selector, this); | 997 return mask.locateSingleElement(selector, this); |
| 996 } | 998 } |
| 997 | 999 |
| 998 TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask) { | 1000 TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask) { |
| 999 assert(isClosed); | 1001 assert(isClosed); |
| 1000 bool canReachAll = true; | 1002 bool canReachAll = true; |
| 1001 if (mask != null) { | 1003 if (mask != null) { |
| 1002 canReachAll = _backend.hasInvokeOnSupport && | 1004 canReachAll = _backend.hasInvokeOnSupport && |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1109 return getMightBePassedToApply(element.expression); | 1111 return getMightBePassedToApply(element.expression); |
| 1110 } | 1112 } |
| 1111 return functionsThatMightBePassedToApply.contains(element); | 1113 return functionsThatMightBePassedToApply.contains(element); |
| 1112 } | 1114 } |
| 1113 | 1115 |
| 1114 @override | 1116 @override |
| 1115 bool getCurrentlyKnownMightBePassedToApply(Element element) { | 1117 bool getCurrentlyKnownMightBePassedToApply(Element element) { |
| 1116 return getMightBePassedToApply(element); | 1118 return getMightBePassedToApply(element); |
| 1117 } | 1119 } |
| 1118 } | 1120 } |
| OLD | NEW |