Chromium Code Reviews| Index: pkg/compiler/lib/src/world.dart |
| diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart |
| index e89f221f5c7ff5f436def89337dcdf130122bb31..c348c770498b6dd26e7e2db9991a00211665c525 100644 |
| --- a/pkg/compiler/lib/src/world.dart |
| +++ b/pkg/compiler/lib/src/world.dart |
| @@ -41,6 +41,43 @@ abstract class ClassWorld { |
| CoreClasses get coreClasses; |
| + /// Returns `true` if the class world is closed. |
| + bool get isClosed; |
| + |
| + /// Returns `true` if closed-world assumptions can be made, that is, |
| + /// incremental compilation isn't enabled. |
| + bool get hasClosedWorldAssumption; |
| + |
| + /// Returns a string representation of the closed world. |
| + /// |
| + /// If [cls] is provided, the dump will contain only classes related to [cls]. |
| + String dump([ClassElement cls]); |
|
Harry Terkelsen
2016/09/23 17:20:27
@OnlyForTesting? Or whatever the annotation is?
Johnni Winther
2016/09/26 14:02:47
Haven't heard of it. Can you find its exactly loca
|
| + |
| + /// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies |
| + /// of known classes. |
| + /// |
| + /// This method is only provided for testing. For queries on classes, use the |
| + /// methods defined in [ClassWorld]. |
| + ClassHierarchyNode getClassHierarchyNode(ClassElement cls); |
| + |
| + /// Returns [ClassSet] for [cls] used to model the extends and implements |
| + /// relations of known classes. |
| + /// |
| + /// This method is only provided for testing. For queries on classes, use the |
| + /// methods defined in [ClassWorld]. |
| + ClassSet getClassSet(ClassElement cls); |
| + |
| + // TODO(johnniwinther): Find a better strategy for caching these. |
| + @deprecated |
| + List<Map<ClassElement, TypeMask>> get canonicalizedTypeMasks; |
| +} |
| + |
| +/// The [ClosedWorld] represents the information known about a program when |
| +/// compiling with closed-world semantics. |
| +/// |
| +/// This expands [ClassWorld] with information about live functions, |
| +/// side effects, and selectors with known single targets. |
| +abstract class ClosedWorld extends ClassWorld { |
| /// Returns `true` if [cls] is either directly or indirectly instantiated. |
| bool isInstantiated(ClassElement cls); |
| @@ -54,9 +91,6 @@ abstract class ClassWorld { |
| /// Returns `true` if [cls] is implemented by an instantiated class. |
| bool isImplemented(ClassElement cls); |
| - /// Returns `true` if the class world is closed. |
| - bool get isClosed; |
| - |
| /// Return `true` if [x] is a subclass of [y]. |
| bool isSubclassOf(ClassElement x, ClassElement y); |
| @@ -155,40 +189,6 @@ abstract class ClassWorld { |
| /// Returns `true` if any subclass of [superclass] implements [type]. |
| bool hasAnySubclassThatImplements(ClassElement superclass, ClassElement type); |
| - /// Returns `true` if closed-world assumptions can be made, that is, |
| - /// incremental compilation isn't enabled. |
| - bool get hasClosedWorldAssumption; |
| - |
| - /// Returns a string representation of the closed world. |
| - /// |
| - /// If [cls] is provided, the dump will contain only classes related to [cls]. |
| - String dump([ClassElement cls]); |
| - |
| - /// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies |
| - /// of known classes. |
| - /// |
| - /// This method is only provided for testing. For queries on classes, use the |
| - /// methods defined in [ClassWorld]. |
| - ClassHierarchyNode getClassHierarchyNode(ClassElement cls); |
| - |
| - /// Returns [ClassSet] for [cls] used to model the extends and implements |
| - /// relations of known classes. |
| - /// |
| - /// This method is only provided for testing. For queries on classes, use the |
| - /// methods defined in [ClassWorld]. |
| - ClassSet getClassSet(ClassElement cls); |
| - |
| - // TODO(johnniwinther): Find a better strategy for caching these. |
| - @deprecated |
| - List<Map<ClassElement, TypeMask>> get canonicalizedTypeMasks; |
| -} |
| - |
| -/// The [ClosedWorld] represents the information known about a program when |
| -/// compiling with closed-world semantics. |
| -/// |
| -/// This expands [ClassWorld] with information about live functions, |
| -/// side effects, and selectors with known single targets. |
| -abstract class ClosedWorld extends ClassWorld { |
| /// Returns the [FunctionSet] containing all live functions in the closed |
| /// world. |
| FunctionSet get allFunctions; |
| @@ -305,6 +305,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| /// Returns `true` if [x] is a subtype of [y], that is, if [x] implements an |
| /// instance of [y]. |
| bool isSubtypeOf(ClassElement x, ClassElement y) { |
| + assert(isClosed); |
| assert(checkInvariants(x)); |
| assert(checkInvariants(y, mustBeInstantiated: false)); |
| @@ -317,6 +318,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| /// Return `true` if [x] is a (non-strict) subclass of [y]. |
| bool isSubclassOf(ClassElement x, ClassElement y) { |
| + assert(isClosed); |
| assert(checkInvariants(x)); |
| assert(checkInvariants(y)); |
| @@ -331,30 +333,35 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| @override |
| bool isInstantiated(ClassElement cls) { |
| + assert(isClosed); |
| ClassHierarchyNode node = _classHierarchyNodes[cls.declaration]; |
| return node != null && node.isInstantiated; |
| } |
| @override |
| bool isDirectlyInstantiated(ClassElement cls) { |
| + assert(isClosed); |
| ClassHierarchyNode node = _classHierarchyNodes[cls.declaration]; |
| return node != null && node.isDirectlyInstantiated; |
| } |
| @override |
| bool isIndirectlyInstantiated(ClassElement cls) { |
| + assert(isClosed); |
| ClassHierarchyNode node = _classHierarchyNodes[cls.declaration]; |
| return node != null && node.isIndirectlyInstantiated; |
| } |
| /// Returns `true` if [cls] is implemented by an instantiated class. |
| bool isImplemented(ClassElement cls) { |
| + assert(isClosed); |
| return _compiler.resolverWorld.isImplemented(cls); |
| } |
| /// Returns an iterable over the directly instantiated classes that extend |
| /// [cls] possibly including [cls] itself, if it is live. |
| Iterable<ClassElement> subclassesOf(ClassElement cls) { |
| + assert(isClosed); |
| ClassHierarchyNode hierarchy = _classHierarchyNodes[cls.declaration]; |
| if (hierarchy == null) return const <ClassElement>[]; |
| return hierarchy.subclassesByMask(ClassHierarchyNode.DIRECTLY_INSTANTIATED); |
| @@ -363,6 +370,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| /// Returns an iterable over the directly instantiated classes that extend |
| /// [cls] _not_ including [cls] itself. |
| Iterable<ClassElement> strictSubclassesOf(ClassElement cls) { |
| + assert(isClosed); |
| ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration]; |
| if (subclasses == null) return const <ClassElement>[]; |
| return subclasses.subclassesByMask(ClassHierarchyNode.DIRECTLY_INSTANTIATED, |
| @@ -372,6 +380,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| /// Returns the number of live classes that extend [cls] _not_ |
| /// including [cls] itself. |
| int strictSubclassCount(ClassElement cls) { |
| + assert(isClosed); |
| ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration]; |
| if (subclasses == null) return 0; |
| return subclasses.instantiatedSubclassCount; |
| @@ -381,6 +390,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| /// itself. |
| void forEachStrictSubclassOf( |
| ClassElement cls, IterationStep f(ClassElement cls)) { |
| + assert(isClosed); |
| ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration]; |
| if (subclasses == null) return; |
| subclasses.forEachSubclass(f, ClassHierarchyNode.DIRECTLY_INSTANTIATED, |
| @@ -390,6 +400,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| /// Returns `true` if [predicate] applies to any live class that extend [cls] |
| /// _not_ including [cls] itself. |
| bool anyStrictSubclassOf(ClassElement cls, bool predicate(ClassElement cls)) { |
| + assert(isClosed); |
| ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration]; |
| if (subclasses == null) return false; |
| return subclasses.anySubclass( |
| @@ -400,6 +411,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| /// Returns an iterable over the directly instantiated that implement [cls] |
| /// possibly including [cls] itself, if it is live. |
| Iterable<ClassElement> subtypesOf(ClassElement cls) { |
| + assert(isClosed); |
| ClassSet classSet = _classSets[cls.declaration]; |
| if (classSet == null) { |
| return const <ClassElement>[]; |
| @@ -411,6 +423,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| /// Returns an iterable over the directly instantiated that implement [cls] |
| /// _not_ including [cls]. |
| Iterable<ClassElement> strictSubtypesOf(ClassElement cls) { |
| + assert(isClosed); |
| ClassSet classSet = _classSets[cls.declaration]; |
| if (classSet == null) { |
| return const <ClassElement>[]; |
| @@ -423,6 +436,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| /// Returns the number of live classes that implement [cls] _not_ |
| /// including [cls] itself. |
| int strictSubtypeCount(ClassElement cls) { |
| + assert(isClosed); |
| ClassSet classSet = _classSets[cls.declaration]; |
| if (classSet == null) return 0; |
| return classSet.instantiatedSubtypeCount; |
| @@ -432,6 +446,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| /// itself. |
| void forEachStrictSubtypeOf( |
| ClassElement cls, IterationStep f(ClassElement cls)) { |
| + assert(isClosed); |
| ClassSet classSet = _classSets[cls.declaration]; |
| if (classSet == null) return; |
| classSet.forEachSubtype(f, ClassHierarchyNode.DIRECTLY_INSTANTIATED, |
| @@ -441,6 +456,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| /// Returns `true` if [predicate] applies to any live class that extend [cls] |
| /// _not_ including [cls] itself. |
| bool anyStrictSubtypeOf(ClassElement cls, bool predicate(ClassElement cls)) { |
| + assert(isClosed); |
| ClassSet classSet = _classSets[cls.declaration]; |
| if (classSet == null) return false; |
| return classSet.anySubtype( |
| @@ -450,6 +466,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| /// Returns `true` if [a] and [b] have any known common subtypes. |
| bool haveAnyCommonSubtypes(ClassElement a, ClassElement b) { |
| + assert(isClosed); |
| ClassSet classSetA = _classSets[a.declaration]; |
| ClassSet classSetB = _classSets[b.declaration]; |
| if (classSetA == null || classSetB == null) return false; |
| @@ -466,6 +483,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| /// Returns `true` if any directly instantiated class other than [cls] extends |
| /// [cls]. |
| bool hasAnyStrictSubclass(ClassElement cls) { |
| + assert(isClosed); |
| ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration]; |
| if (subclasses == null) return false; |
| return subclasses.isIndirectlyInstantiated; |
| @@ -480,6 +498,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| /// Returns `true` if all directly instantiated classes that implement [cls] |
| /// extend it. |
| bool hasOnlySubclasses(ClassElement cls) { |
| + assert(isClosed); |
| // TODO(johnniwinther): move this to ClassSet? |
| if (cls == coreClasses.objectClass) return true; |
| ClassSet classSet = _classSets[cls.declaration]; |
| @@ -492,6 +511,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| @override |
| ClassElement getLubOfInstantiatedSubclasses(ClassElement cls) { |
| + assert(isClosed); |
| if (backend.isJsInterop(cls)) { |
| return backend.helpers.jsJavaScriptObjectClass; |
| } |
| @@ -503,6 +523,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| @override |
| ClassElement getLubOfInstantiatedSubtypes(ClassElement cls) { |
| + assert(isClosed); |
| if (backend.isJsInterop(cls)) { |
| return backend.helpers.jsJavaScriptObjectClass; |
| } |
| @@ -512,6 +533,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| /// Returns an iterable over the common supertypes of the [classes]. |
| Iterable<ClassElement> commonSupertypesOf(Iterable<ClassElement> classes) { |
| + assert(isClosed); |
| Iterator<ClassElement> iterator = classes.iterator; |
| if (!iterator.moveNext()) return const <ClassElement>[]; |
| @@ -588,12 +610,14 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| /// Returns `true` if [cls] is mixed into a live class. |
| bool isUsedAsMixin(ClassElement cls) { |
| + assert(isClosed); |
| return !mixinUsesOf(cls).isEmpty; |
| } |
| /// Returns `true` if any live class that mixes in [cls] implements [type]. |
| bool hasAnySubclassOfMixinUseThatImplements( |
| ClassElement cls, ClassElement type) { |
| + assert(isClosed); |
| return mixinUsesOf(cls) |
| .any((use) => hasAnySubclassThatImplements(use, type)); |
| } |
| @@ -601,11 +625,13 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| /// Returns `true` if any live class that mixes in [mixin] is also a subclass |
| /// of [superclass]. |
| bool hasAnySubclassThatMixes(ClassElement superclass, ClassElement mixin) { |
| + assert(isClosed); |
| return mixinUsesOf(mixin).any((each) => each.isSubclassOf(superclass)); |
| } |
| /// Returns `true` if [cls] or any superclass mixes in [mixin]. |
| bool isSubclassOfMixinUseOf(ClassElement cls, ClassElement mixin) { |
| + assert(isClosed); |
| if (isUsedAsMixin(mixin)) { |
| ClassElement current = cls.declaration; |
| mixin = mixin.declaration; |
| @@ -624,6 +650,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| /// Returns `true` if every subtype of [x] is a subclass of [y] or a subclass |
| /// of a mixin application of [y]. |
| bool everySubtypeIsSubclassOfOrMixinUseOf(ClassElement x, ClassElement y) { |
| + assert(isClosed); |
| x = x.declaration; |
| y = y.declaration; |
| Map<ClassElement, bool> secondMap = |
| @@ -635,6 +662,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { |
| /// Returns `true` if any subclass of [superclass] implements [type]. |
| bool hasAnySubclassThatImplements( |
| ClassElement superclass, ClassElement type) { |
| + assert(isClosed); |
| Set<ClassElement> subclasses = typesImplementedBySubclassesOf(superclass); |
| if (subclasses == null) return false; |
| return subclasses.contains(type); |