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 |