Index: pkg/compiler/lib/src/world.dart |
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart |
index f04d10394c4c9aa3b02124dd02f1241c0128c2a9..16017f45d6c12e9cb145f6bc285e605a2aa82569 100644 |
--- a/pkg/compiler/lib/src/world.dart |
+++ b/pkg/compiler/lib/src/world.dart |
@@ -62,9 +62,16 @@ abstract class ClassWorld { |
/// The [ClassElement] for the [String] class defined in 'dart:core'. |
ClassElement get stringClass; |
- /// Returns `true` if [cls] is instantiated. |
+ /// Returns `true` if [cls] is either directly or indirectly instantiated. |
bool isInstantiated(ClassElement cls); |
+ /// Returns `true` if [cls] is directly instantiated. |
+ bool isDirectlyInstantiated(ClassElement cls); |
+ |
+ /// Returns `true` if [cls] is indirectly instantiated, that is through a |
+ /// subclass. |
+ bool isIndirectlyInstantiated(ClassElement cls); |
+ |
/// Returns `true` if [cls] is implemented by an instantiated class. |
bool isImplemented(ClassElement cls); |
@@ -106,6 +113,16 @@ abstract class ClassWorld { |
/// Returns `true` if all live classes that implement [cls] extend it. |
bool hasOnlySubclasses(ClassElement cls); |
+ /// Returns the most specific subclass of [cls] (including [cls]) that is |
+ /// directly instantiated or a superclass of all directly instantiated |
+ /// subclasses. If [cls] is not instantiated, `null` is returned. |
+ ClassElement getLeastUpperInstantiatedSubclass(ClassElement cls); |
+ |
+ /// Returns the most specific subtype of [cls] (including [cls]) that is |
+ /// directly instantiated or a superclass of all directly instantiated |
+ /// subtypes. If no subtypes of [cls] are instantiated, `null` is returned. |
+ ClassElement getLeastUpperInstantiatedSubtype(ClassElement cls); |
+ |
/// Returns an iterable over the common supertypes of the [classes]. |
Iterable<ClassElement> commonSupertypesOf(Iterable<ClassElement> classes); |
@@ -190,10 +207,22 @@ class World implements ClassWorld { |
return false; |
} |
- /// Returns `true` if [cls] is instantiated either directly or through a |
- /// subclass. |
+ @override |
bool isInstantiated(ClassElement cls) { |
- return compiler.resolverWorld.isInstantiated(cls); |
+ ClassHierarchyNode node = _classHierarchyNodes[cls.declaration]; |
+ return node != null && node.isInstantiated; |
+ } |
+ |
+ @override |
+ bool isDirectlyInstantiated(ClassElement cls) { |
+ ClassHierarchyNode node = _classHierarchyNodes[cls.declaration]; |
+ return node != null && node.isDirectlyInstantiated; |
+ } |
+ |
+ @override |
+ bool isIndirectlyInstantiated(ClassElement cls) { |
+ ClassHierarchyNode node = _classHierarchyNodes[cls.declaration]; |
+ return node != null && node.isIndirectlyInstantiated; |
} |
/// Returns `true` if [cls] is implemented by an instantiated class. |
@@ -287,6 +316,20 @@ class World implements ClassWorld { |
return subclasses != null && (subclasses.length == subtypes.length); |
} |
+ @override |
+ ClassElement getLeastUpperInstantiatedSubclass(ClassElement cls) { |
+ ClassHierarchyNode hierarchy = _classHierarchyNodes[cls.declaration]; |
+ return hierarchy != null |
+ ? hierarchy.getLeastUpperInstantiatedSubclass() : null; |
+ } |
+ |
+ @override |
+ ClassElement getLeastUpperInstantiatedSubtype(ClassElement cls) { |
+ ClassSet classSet = _classSets[cls.declaration]; |
+ return classSet != null |
+ ? classSet.getLeastUpperInstantiatedSubtype() : null; |
+ } |
+ |
/// Returns an iterable over the common supertypes of the [classes]. |
Iterable<ClassElement> commonSupertypesOf(Iterable<ClassElement> classes) { |
Iterator<ClassElement> iterator = classes.iterator; |
@@ -499,7 +542,6 @@ class World implements ClassWorld { |
ClassElement cls, |
{bool directlyInstantiated: false, |
bool indirectlyInstantiated: false}) { |
- assert(!directlyInstantiated || isInstantiated(cls)); |
ClassHierarchyNode node = getClassHierarchyNode(cls); |
bool changed = false; |
if (directlyInstantiated && !node.isDirectlyInstantiated) { |
@@ -514,6 +556,13 @@ class World implements ClassWorld { |
updateClassHierarchyNodeForClass( |
cls.superclass, indirectlyInstantiated: true); |
} |
+ // Ensure that classes implicitly implementing `Function` are in its |
+ // subtype set. |
+ if (cls != coreClasses.functionClass && |
+ cls.implementsFunction(compiler)) { |
+ ClassSet subtypeSet = _ensureClassSet(coreClasses.functionClass); |
+ subtypeSet.addSubtype(node); |
+ } |
} |
void addSubtypes(ClassElement cls) { |