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'; |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 ConstantSystem get constantSystem => _backend.constantSystem; | 465 ConstantSystem get constantSystem => _backend.constantSystem; |
466 | 466 |
467 TypeMask getCachedMask(ClassEntity base, int flags, TypeMask createMask()) { | 467 TypeMask getCachedMask(ClassEntity base, int flags, TypeMask createMask()) { |
468 Map<ClassEntity, TypeMask> cachedMasks = | 468 Map<ClassEntity, TypeMask> cachedMasks = |
469 _canonicalizedTypeMasks[flags] ??= <ClassEntity, TypeMask>{}; | 469 _canonicalizedTypeMasks[flags] ??= <ClassEntity, TypeMask>{}; |
470 return cachedMasks.putIfAbsent(base, createMask); | 470 return cachedMasks.putIfAbsent(base, createMask); |
471 } | 471 } |
472 | 472 |
473 bool _checkClass(ClassEntity cls); | 473 bool _checkClass(ClassEntity cls); |
474 | 474 |
| 475 bool _checkInvariants(ClassEntity cls, {bool mustBeInstantiated: true}); |
| 476 |
475 @override | 477 @override |
476 bool isInstantiated(ClassEntity cls) { | 478 bool isInstantiated(ClassEntity cls) { |
477 assert(_checkClass(cls)); | 479 assert(_checkClass(cls)); |
478 ClassHierarchyNode node = _classHierarchyNodes[cls]; | 480 ClassHierarchyNode node = _classHierarchyNodes[cls]; |
479 return node != null && node.isInstantiated; | 481 return node != null && node.isInstantiated; |
480 } | 482 } |
481 | 483 |
482 @override | 484 @override |
483 bool isDirectlyInstantiated(ClassEntity cls) { | 485 bool isDirectlyInstantiated(ClassEntity cls) { |
484 assert(_checkClass(cls)); | 486 assert(_checkClass(cls)); |
(...skipping 23 matching lines...) Expand all Loading... |
508 } | 510 } |
509 | 511 |
510 @override | 512 @override |
511 bool isAbstract(ClassEntity cls) => cls.isAbstract; | 513 bool isAbstract(ClassEntity cls) => cls.isAbstract; |
512 | 514 |
513 /// Returns `true` if [cls] is implemented by an instantiated class. | 515 /// Returns `true` if [cls] is implemented by an instantiated class. |
514 bool isImplemented(ClassEntity cls) { | 516 bool isImplemented(ClassEntity cls) { |
515 return _resolverWorld.isImplemented(cls); | 517 return _resolverWorld.isImplemented(cls); |
516 } | 518 } |
517 | 519 |
| 520 /// Returns `true` if [x] is a subtype of [y], that is, if [x] implements an |
| 521 /// instance of [y]. |
| 522 bool isSubtypeOf(ClassEntity x, ClassEntity y) { |
| 523 assert(_checkInvariants(x)); |
| 524 assert(_checkInvariants(y, mustBeInstantiated: false)); |
| 525 return _classSets[y].hasSubtype(_classHierarchyNodes[x]); |
| 526 } |
| 527 |
| 528 /// Return `true` if [x] is a (non-strict) subclass of [y]. |
| 529 bool isSubclassOf(ClassEntity x, ClassEntity y) { |
| 530 assert(_checkInvariants(x)); |
| 531 assert(_checkInvariants(y)); |
| 532 return _classHierarchyNodes[y].hasSubclass(_classHierarchyNodes[x]); |
| 533 } |
| 534 |
518 /// Returns an iterable over the directly instantiated classes that extend | 535 /// Returns an iterable over the directly instantiated classes that extend |
519 /// [cls] possibly including [cls] itself, if it is live. | 536 /// [cls] possibly including [cls] itself, if it is live. |
520 Iterable<ClassEntity> subclassesOf(ClassEntity cls) { | 537 Iterable<ClassEntity> subclassesOf(ClassEntity cls) { |
521 assert(_checkClass(cls)); | 538 assert(_checkClass(cls)); |
522 ClassHierarchyNode hierarchy = _classHierarchyNodes[cls]; | 539 ClassHierarchyNode hierarchy = _classHierarchyNodes[cls]; |
523 if (hierarchy == null) return const <ClassEntity>[]; | 540 if (hierarchy == null) return const <ClassEntity>[]; |
524 return hierarchy | 541 return hierarchy |
525 .subclassesByMask(ClassHierarchyNode.EXPLICITLY_INSTANTIATED); | 542 .subclassesByMask(ClassHierarchyNode.EXPLICITLY_INSTANTIATED); |
526 } | 543 } |
527 | 544 |
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
920 // TODO(johnniwinther): Reinsert this or similar invariant. Currently | 937 // TODO(johnniwinther): Reinsert this or similar invariant. Currently |
921 // various call sites use uninstantiated classes for isSubtypeOf or | 938 // various call sites use uninstantiated classes for isSubtypeOf or |
922 // isSubclassOf. Some are valid, some are not. Work out better invariants | 939 // isSubclassOf. Some are valid, some are not. Work out better invariants |
923 // to catch the latter. | 940 // to catch the latter. |
924 (!mustBeInstantiated || | 941 (!mustBeInstantiated || |
925 invariant(cls, isInstantiated(cls), | 942 invariant(cls, isInstantiated(cls), |
926 message: '$cls is not instantiated.'))*/ | 943 message: '$cls is not instantiated.'))*/ |
927 ; | 944 ; |
928 } | 945 } |
929 | 946 |
930 /// Returns `true` if [x] is a subtype of [y], that is, if [x] implements an | |
931 /// instance of [y]. | |
932 bool isSubtypeOf(ClassElement x, ClassElement y) { | |
933 assert(_checkInvariants(x)); | |
934 assert(_checkInvariants(y, mustBeInstantiated: false)); | |
935 | |
936 if (y == commonElements.objectClass) return true; | |
937 if (x == commonElements.objectClass) return false; | |
938 if (x.asInstanceOf(y) != null) return true; | |
939 if (y != commonElements.functionClass) return false; | |
940 return x.callType != null; | |
941 } | |
942 | |
943 /// Return `true` if [x] is a (non-strict) subclass of [y]. | |
944 bool isSubclassOf(ClassElement x, ClassElement y) { | |
945 assert(_checkInvariants(x)); | |
946 assert(_checkInvariants(y)); | |
947 | |
948 if (y == commonElements.objectClass) return true; | |
949 if (x == commonElements.objectClass) return false; | |
950 while (x != null && x.hierarchyDepth >= y.hierarchyDepth) { | |
951 if (x == y) return true; | |
952 x = x.superclass; | |
953 } | |
954 return false; | |
955 } | |
956 | |
957 /// Returns an iterable over the common supertypes of the [classes]. | 947 /// Returns an iterable over the common supertypes of the [classes]. |
958 Iterable<ClassElement> commonSupertypesOf(Iterable<ClassElement> classes) { | 948 Iterable<ClassElement> commonSupertypesOf(Iterable<ClassElement> classes) { |
959 Iterator<ClassElement> iterator = classes.iterator; | 949 Iterator<ClassElement> iterator = classes.iterator; |
960 if (!iterator.moveNext()) return const <ClassElement>[]; | 950 if (!iterator.moveNext()) return const <ClassElement>[]; |
961 | 951 |
962 ClassElement cls = iterator.current; | 952 ClassElement cls = iterator.current; |
963 assert(_checkInvariants(cls)); | 953 assert(_checkInvariants(cls)); |
964 OrderedTypeSet typeSet = cls.allSupertypesAndSelf; | 954 OrderedTypeSet typeSet = cls.allSupertypesAndSelf; |
965 if (!iterator.moveNext()) return typeSet.types.map((type) => type.element); | 955 if (!iterator.moveNext()) return typeSet.types.map((type) => type.element); |
966 | 956 |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1213 return getMightBePassedToApply(element.expression); | 1203 return getMightBePassedToApply(element.expression); |
1214 } | 1204 } |
1215 return functionsThatMightBePassedToApply.contains(element); | 1205 return functionsThatMightBePassedToApply.contains(element); |
1216 } | 1206 } |
1217 | 1207 |
1218 @override | 1208 @override |
1219 bool getCurrentlyKnownMightBePassedToApply(Element element) { | 1209 bool getCurrentlyKnownMightBePassedToApply(Element element) { |
1220 return getMightBePassedToApply(element); | 1210 return getMightBePassedToApply(element); |
1221 } | 1211 } |
1222 } | 1212 } |
OLD | NEW |