Index: pkg/compiler/lib/src/world.dart |
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart |
index 6cfa45f9700bf74ff7d9ffbc36b8351f07834fe1..40eba3eac420db6cf0e71283892e75324dc77a13 100644 |
--- a/pkg/compiler/lib/src/world.dart |
+++ b/pkg/compiler/lib/src/world.dart |
@@ -67,6 +67,9 @@ abstract class ClassWorld { |
/// Returns `true` if [cls] is instantiated. |
bool isInstantiated(ClassElement cls); |
+ /// 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; |
@@ -124,6 +127,9 @@ abstract class ClassWorld { |
/// 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. |
+ String dump(); |
} |
class World implements ClassWorld { |
@@ -146,10 +152,11 @@ class World implements ClassWorld { |
invariant(cls, cls.isDeclaration, |
message: '$cls must be the declaration.') && |
invariant(cls, cls.isResolved, |
- message: '$cls must be resolved.') && |
+ message: '$cls must be resolved.')/* && |
+ // TODO(johnniwinther): Reinsert this or similar invariant. |
(!mustBeInstantiated || |
invariant(cls, isInstantiated(cls), |
- message: '$cls is not instantiated.')); |
+ message: '$cls is not instantiated.'))*/; |
} |
/// Returns `true` if [x] is a subtype of [y], that is, if [x] implements an |
@@ -179,11 +186,17 @@ class World implements ClassWorld { |
return false; |
} |
- /// Returns `true` if [cls] is instantiated. |
+ /// Returns `true` if [cls] is instantiated either directly or through a |
+ /// subclass. |
bool isInstantiated(ClassElement cls) { |
return compiler.resolverWorld.isInstantiated(cls); |
} |
+ /// Returns `true` if [cls] is implemented by an instantiated class. |
+ bool isImplemented(ClassElement cls) { |
+ 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) { |
@@ -309,9 +322,21 @@ class World implements ClassWorld { |
if (_liveMixinUses == null) { |
_liveMixinUses = new Map<ClassElement, List<MixinApplicationElement>>(); |
for (ClassElement mixin in _mixinUses.keys) { |
- Iterable<MixinApplicationElement> uses = |
- _mixinUses[mixin].where(isInstantiated); |
- if (uses.isNotEmpty) _liveMixinUses[mixin] = uses.toList(); |
+ List<MixinApplicationElement> uses = <MixinApplicationElement>[]; |
+ void addLiveUse(MixinApplicationElement mixinApplication) { |
karlklose
2015/09/17 10:42:38
Consider push this local function to the beginning
Johnni Winther
2015/09/17 12:56:40
It uses [uses]. Added an empty line before and aft
|
+ if (isInstantiated(mixinApplication)) { |
+ uses.add(mixinApplication); |
+ } else if (mixinApplication.isNamedMixinApplication) { |
+ List<MixinApplicationElement> next = _mixinUses[mixinApplication]; |
+ if (next != null) { |
+ next.forEach(addLiveUse); |
+ } |
+ } |
+ } |
+ _mixinUses[mixin].forEach(addLiveUse); |
+ if (uses.isNotEmpty) { |
+ _liveMixinUses[mixin] = uses; |
+ } |
} |
} |
Iterable<MixinApplicationElement> uses = _liveMixinUses[cls]; |
@@ -505,6 +530,15 @@ class World implements ClassWorld { |
compiler.resolverWorld.directlyInstantiatedClasses.forEach(addSubtypes); |
} |
+ @override |
+ String dump() { |
+ StringBuffer sb = new StringBuffer(); |
+ sb.write("Instantiated classes in the closed world:\n"); |
+ getClassHierarchyNode(compiler.objectClass) |
+ .printOn(sb, ' ', instantiatedOnly: true); |
+ return sb.toString(); |
+ } |
+ |
void registerMixinUse(MixinApplicationElement mixinApplication, |
ClassElement mixin) { |
// TODO(johnniwinther): Add map restricted to live classes. |