| 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.dart'; | 8 import 'common.dart'; |
| 9 import 'constants/constant_system.dart'; | 9 import 'constants/constant_system.dart'; |
| 10 import 'common_elements.dart' show CommonElements, ElementEnvironment; | 10 import 'common_elements.dart' show CommonElements, ElementEnvironment; |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 /// If we're calling bar on an object of type D, we don't need the handler | 246 /// If we're calling bar on an object of type D, we don't need the handler |
| 247 /// either because all objects of type D implement bar through inheritance. | 247 /// either because all objects of type D implement bar through inheritance. |
| 248 /// | 248 /// |
| 249 /// If we're calling bar on an object of type A we do need the handler because | 249 /// If we're calling bar on an object of type A we do need the handler because |
| 250 /// we may have to call B.noSuchMethod since B does not implement bar. | 250 /// we may have to call B.noSuchMethod since B does not implement bar. |
| 251 bool needsNoSuchMethod(ClassEntity cls, Selector selector, ClassQuery query); | 251 bool needsNoSuchMethod(ClassEntity cls, Selector selector, ClassQuery query); |
| 252 | 252 |
| 253 /// Returns whether [element] will be the one used at runtime when being | 253 /// Returns whether [element] will be the one used at runtime when being |
| 254 /// invoked on an instance of [cls]. [selector] is used to ensure library | 254 /// invoked on an instance of [cls]. [selector] is used to ensure library |
| 255 /// privacy is taken into account. | 255 /// privacy is taken into account. |
| 256 bool hasElementIn(ClassEntity cls, Selector selector, Entity element); | 256 bool hasElementIn( |
| 257 covariant ClassEntity cls, Selector selector, covariant Entity element); |
| 257 | 258 |
| 258 /// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies | 259 /// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies |
| 259 /// of known classes. | 260 /// of known classes. |
| 260 /// | 261 /// |
| 261 /// This method is only provided for testing. For queries on classes, use the | 262 /// This method is only provided for testing. For queries on classes, use the |
| 262 /// methods defined in [ClosedWorld]. | 263 /// methods defined in [ClosedWorld]. |
| 263 ClassHierarchyNode getClassHierarchyNode(ClassEntity cls); | 264 ClassHierarchyNode getClassHierarchyNode(ClassEntity cls); |
| 264 | 265 |
| 265 /// Returns [ClassSet] for [cls] used to model the extends and implements | 266 /// Returns [ClassSet] for [cls] used to model the extends and implements |
| 266 /// relations of known classes. | 267 /// relations of known classes. |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 | 359 |
| 359 /// Registers that [element] is called in a loop. | 360 /// Registers that [element] is called in a loop. |
| 360 // TODO(johnniwinther): Is this 'potentially called' or 'known to be called'? | 361 // TODO(johnniwinther): Is this 'potentially called' or 'known to be called'? |
| 361 void addFunctionCalledInLoop(Entity element); | 362 void addFunctionCalledInLoop(Entity element); |
| 362 | 363 |
| 363 /// Registers that [element] is guaranteed not to throw an exception. | 364 /// Registers that [element] is guaranteed not to throw an exception. |
| 364 void registerCannotThrow(Entity element); | 365 void registerCannotThrow(Entity element); |
| 365 | 366 |
| 366 /// Adds the closure class [cls] to the inference world. The class is | 367 /// Adds the closure class [cls] to the inference world. The class is |
| 367 /// considered directly instantiated. | 368 /// considered directly instantiated. |
| 368 void registerClosureClass(ClassElement cls); | 369 void registerClosureClass(covariant ClassElement cls); |
| 369 } | 370 } |
| 370 | 371 |
| 371 abstract class OpenWorld implements World { | 372 abstract class OpenWorld implements World { |
| 372 /// Called to add [cls] to the set of known classes. | 373 /// Called to add [cls] to the set of known classes. |
| 373 /// | 374 /// |
| 374 /// This ensures that class hierarchy queries can be performed on [cls] and | 375 /// This ensures that class hierarchy queries can be performed on [cls] and |
| 375 /// classes that extend or implement it. | 376 /// classes that extend or implement it. |
| 376 void registerClass(ClassEntity cls); | 377 void registerClass(covariant ClassEntity cls); |
| 377 | 378 |
| 378 void registerUsedElement(MemberEntity element); | 379 void registerUsedElement(MemberEntity element); |
| 379 void registerTypedef(TypedefElement typedef); | 380 void registerTypedef(TypedefElement typedef); |
| 380 | 381 |
| 381 ClosedWorld closeWorld(); | 382 ClosedWorld closeWorld(); |
| 382 | 383 |
| 383 /// Returns an iterable over all mixin applications that mixin [cls]. | 384 /// Returns an iterable over all mixin applications that mixin [cls]. |
| 384 Iterable<ClassEntity> allMixinUsesOf(ClassEntity cls); | 385 Iterable<ClassEntity> allMixinUsesOf(ClassEntity cls); |
| 385 } | 386 } |
| 386 | 387 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 477 CommonMasks get commonMasks { | 478 CommonMasks get commonMasks { |
| 478 return _commonMasks; | 479 return _commonMasks; |
| 479 } | 480 } |
| 480 | 481 |
| 481 TypeMask getCachedMask(ClassEntity base, int flags, TypeMask createMask()) { | 482 TypeMask getCachedMask(ClassEntity base, int flags, TypeMask createMask()) { |
| 482 Map<ClassEntity, TypeMask> cachedMasks = | 483 Map<ClassEntity, TypeMask> cachedMasks = |
| 483 _canonicalizedTypeMasks[flags] ??= <ClassEntity, TypeMask>{}; | 484 _canonicalizedTypeMasks[flags] ??= <ClassEntity, TypeMask>{}; |
| 484 return cachedMasks.putIfAbsent(base, createMask); | 485 return cachedMasks.putIfAbsent(base, createMask); |
| 485 } | 486 } |
| 486 | 487 |
| 487 bool checkEntity(Entity element); | 488 bool checkEntity(covariant Entity element); |
| 488 | 489 |
| 489 bool checkClass(ClassEntity cls); | 490 bool checkClass(covariant ClassEntity cls); |
| 490 | 491 |
| 491 bool checkInvariants(ClassEntity cls, {bool mustBeInstantiated: true}); | 492 bool checkInvariants(covariant ClassEntity cls, |
| 493 {bool mustBeInstantiated: true}); |
| 492 | 494 |
| 493 OrderedTypeSet getOrderedTypeSet(ClassEntity cls); | 495 OrderedTypeSet getOrderedTypeSet(covariant ClassEntity cls); |
| 494 | 496 |
| 495 int getHierarchyDepth(ClassEntity cls); | 497 int getHierarchyDepth(covariant ClassEntity cls); |
| 496 | 498 |
| 497 ClassEntity getSuperClass(ClassEntity cls); | 499 ClassEntity getSuperClass(covariant ClassEntity cls); |
| 498 | 500 |
| 499 Iterable<ClassEntity> getInterfaces(ClassEntity cls); | 501 Iterable<ClassEntity> getInterfaces(covariant ClassEntity cls); |
| 500 | 502 |
| 501 ClassEntity getAppliedMixin(ClassEntity cls); | 503 ClassEntity getAppliedMixin(covariant ClassEntity cls); |
| 502 | 504 |
| 503 bool isNamedMixinApplication(ClassEntity cls); | 505 bool isNamedMixinApplication(covariant ClassEntity cls); |
| 504 | 506 |
| 505 @override | 507 @override |
| 506 bool isInstantiated(ClassEntity cls) { | 508 bool isInstantiated(ClassEntity cls) { |
| 507 assert(checkClass(cls)); | 509 assert(checkClass(cls)); |
| 508 ClassHierarchyNode node = _classHierarchyNodes[cls]; | 510 ClassHierarchyNode node = _classHierarchyNodes[cls]; |
| 509 return node != null && node.isInstantiated; | 511 return node != null && node.isInstantiated; |
| 510 } | 512 } |
| 511 | 513 |
| 512 @override | 514 @override |
| 513 bool isDirectlyInstantiated(ClassEntity cls) { | 515 bool isDirectlyInstantiated(ClassEntity cls) { |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 794 /// Returns `true` if any subclass of [superclass] implements [type]. | 796 /// Returns `true` if any subclass of [superclass] implements [type]. |
| 795 bool hasAnySubclassThatImplements(ClassEntity superclass, ClassEntity type) { | 797 bool hasAnySubclassThatImplements(ClassEntity superclass, ClassEntity type) { |
| 796 assert(checkClass(superclass)); | 798 assert(checkClass(superclass)); |
| 797 Set<ClassEntity> subclasses = _typesImplementedBySubclasses[superclass]; | 799 Set<ClassEntity> subclasses = _typesImplementedBySubclasses[superclass]; |
| 798 if (subclasses == null) return false; | 800 if (subclasses == null) return false; |
| 799 return subclasses.contains(type); | 801 return subclasses.contains(type); |
| 800 } | 802 } |
| 801 | 803 |
| 802 /// Returns whether a [selector] call on an instance of [cls] | 804 /// Returns whether a [selector] call on an instance of [cls] |
| 803 /// will hit a method at runtime, and not go through [noSuchMethod]. | 805 /// will hit a method at runtime, and not go through [noSuchMethod]. |
| 804 bool hasConcreteMatch(ClassEntity cls, Selector selector, | 806 bool hasConcreteMatch(covariant ClassEntity cls, Selector selector, |
| 805 {ClassEntity stopAtSuperclass}); | 807 {covariant ClassEntity stopAtSuperclass}); |
| 806 | 808 |
| 807 @override | 809 @override |
| 808 bool needsNoSuchMethod( | 810 bool needsNoSuchMethod( |
| 809 ClassEntity base, Selector selector, ClassQuery query) { | 811 ClassEntity base, Selector selector, ClassQuery query) { |
| 810 /// Returns `true` if subclasses in the [rootNode] tree needs noSuchMethod | 812 /// Returns `true` if subclasses in the [rootNode] tree needs noSuchMethod |
| 811 /// handling. | 813 /// handling. |
| 812 bool subclassesNeedNoSuchMethod(ClassHierarchyNode rootNode) { | 814 bool subclassesNeedNoSuchMethod(ClassHierarchyNode rootNode) { |
| 813 if (!rootNode.isInstantiated) { | 815 if (!rootNode.isInstantiated) { |
| 814 // No subclass needs noSuchMethod handling since they are all | 816 // No subclass needs noSuchMethod handling since they are all |
| 815 // uninstantiated. | 817 // uninstantiated. |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1068 sideEffects.setAllSideEffects(); | 1070 sideEffects.setAllSideEffects(); |
| 1069 sideEffects.setDependsOnSomething(); | 1071 sideEffects.setDependsOnSomething(); |
| 1070 } | 1072 } |
| 1071 } else { | 1073 } else { |
| 1072 sideEffects.add(getSideEffectsOfElement(e)); | 1074 sideEffects.add(getSideEffectsOfElement(e)); |
| 1073 } | 1075 } |
| 1074 } | 1076 } |
| 1075 return sideEffects; | 1077 return sideEffects; |
| 1076 } | 1078 } |
| 1077 | 1079 |
| 1078 SideEffects getSideEffectsOfElement(Entity element) { | 1080 SideEffects getSideEffectsOfElement(covariant Entity element) { |
| 1079 assert(checkEntity(element)); | 1081 assert(checkEntity(element)); |
| 1080 return _sideEffects.putIfAbsent(element, _makeSideEffects); | 1082 return _sideEffects.putIfAbsent(element, _makeSideEffects); |
| 1081 } | 1083 } |
| 1082 | 1084 |
| 1083 static _makeSideEffects() => new SideEffects(); | 1085 static SideEffects _makeSideEffects() => new SideEffects(); |
| 1084 | 1086 |
| 1085 @override | 1087 @override |
| 1086 SideEffects getCurrentlyKnownSideEffects(Entity element) { | 1088 SideEffects getCurrentlyKnownSideEffects(Entity element) { |
| 1087 return getSideEffectsOfElement(element); | 1089 return getSideEffectsOfElement(element); |
| 1088 } | 1090 } |
| 1089 | 1091 |
| 1090 void registerSideEffects(Entity element, SideEffects effects) { | 1092 void registerSideEffects(Entity element, SideEffects effects) { |
| 1091 assert(checkEntity(element)); | 1093 assert(checkEntity(element)); |
| 1092 if (_sideEffectsFreeElements.contains(element)) return; | 1094 if (_sideEffectsFreeElements.contains(element)) return; |
| 1093 _sideEffects[element] = effects; | 1095 _sideEffects[element] = effects; |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1297 // does not see generative constructor bodies because they are | 1299 // does not see generative constructor bodies because they are |
| 1298 // created by the backend. Also, it does not make any distinction | 1300 // created by the backend. Also, it does not make any distinction |
| 1299 // between a constructor and its body for side effects. This | 1301 // between a constructor and its body for side effects. This |
| 1300 // implies that currently, the side effects of a constructor body | 1302 // implies that currently, the side effects of a constructor body |
| 1301 // contain the side effects of the initializers. | 1303 // contain the side effects of the initializers. |
| 1302 assert(!element.isGenerativeConstructorBody); | 1304 assert(!element.isGenerativeConstructorBody); |
| 1303 assert(!element.isField); | 1305 assert(!element.isField); |
| 1304 return super.getSideEffectsOfElement(element); | 1306 return super.getSideEffectsOfElement(element); |
| 1305 } | 1307 } |
| 1306 } | 1308 } |
| OLD | NEW |