Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(341)

Unified Diff: sdk/lib/_internal/compiler/implementation/types/type_mask.dart

Issue 12443005: Add superclasses, subclasses, and subtypes tracking to the world. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix long lines. Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: sdk/lib/_internal/compiler/implementation/types/type_mask.dart
diff --git a/sdk/lib/_internal/compiler/implementation/types/type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
index 1e40622b7ee2e30205672020c7bfa8b06697a679..5bb34a35e9c0b6c40339b4faa54fbed876c6cff3 100644
--- a/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
@@ -92,8 +92,9 @@ class TypeMask {
return unionSubtype(other, compiler);
} else if (isSubtypeOf(base, other.base, compiler)) {
return other.unionSubtype(this, compiler);
+ } else {
+ return unionDisjoint(other, compiler);
}
- return null;
}
TypeMask unionSame(TypeMask other, Compiler compiler) {
@@ -145,6 +146,55 @@ class TypeMask {
: this;
}
+ TypeMask unionDisjoint(TypeMask other, Compiler compiler) {
+ assert(base != other.base);
+ assert(!isSubtypeOf(base, other.base, compiler));
+ assert(!isSubtypeOf(other.base, base, compiler));
+ // If either type mask is a subtype type mask, we cannot use a
+ // subclass type mask to represent their union.
+ bool useSubclass = !isSubtype && !other.isSubtype;
+ // Compute the common supertypes of the two types.
+ ClassElement thisElement = base.element;
+ ClassElement otherElement = other.base.element;
+ Iterable<ClassElement> candidates =
+ compiler.world.commonSupertypesOf(thisElement, otherElement);
+ if (candidates.isEmpty) return null;
+ // Compute the best candidate and its kind.
+ ClassElement bestElement;
+ int bestKind;
+ int bestSize;
+ for (ClassElement candidate in candidates) {
+ Set<ClassElement> subclasses = useSubclass
+ ? compiler.world.subclasses[candidate]
+ : null;
+ int size;
+ int kind;
+ if (subclasses != null &&
+ subclasses.contains(thisElement) &&
+ subclasses.contains(otherElement)) {
+ // If both [this] and [other] are subclasses of the supertype,
+ // then we prefer to construct a subclass type mask because it
+ // will always be at least as small as the corresponding
+ // subtype type mask.
+ kind = SUBCLASS;
+ size = subclasses.length;
+ assert(size <= compiler.world.subtypes[candidate].length);
+ } else {
+ kind = SUBTYPE;
+ size = compiler.world.subtypes[candidate].length;
+ }
+ // Update the best candidate if the new one is better.
+ if (bestElement == null || size < bestSize) {
+ bestElement = candidate;
+ bestSize = size;
+ bestKind = kind;
+ }
+ }
+ return new TypeMask(bestElement.computeType(compiler),
+ bestKind,
+ isNullable || other.isNullable);
+ }
+
TypeMask intersection(TypeMask other, Compiler compiler) {
if (base == other.base) {
return intersectionSame(other, compiler);
@@ -225,19 +275,16 @@ class TypeMask {
return "[$buffer]";
}
- // TODO(kasperl): Move this to the world.
static bool isSubclassOf(DartType x, DartType y, Compiler compiler) {
// TODO(kasperl): Do this error handling earlier.
if (x.kind != TypeKind.INTERFACE) return false;
if (y.kind != TypeKind.INTERFACE) return false;
ClassElement xElement = x.element;
ClassElement yElement = y.element;
- // TODO(kasperl): Fix the discrepancy between subclass/subtype
- // that occurs because of "unseen" classes.
- return isSubtypeOf(x, y, compiler) && xElement.isSubclassOf(yElement);
+ Set<ClassElement> subclasses = compiler.world.subclasses[yElement];
+ return (subclasses != null) ? subclasses.contains(xElement) : false;
}
- // TODO(kasperl): Move this to the world.
static bool isSubtypeOf(DartType x, DartType y, Compiler compiler) {
// TODO(kasperl): Do this error handling earlier.
if (x.kind != TypeKind.INTERFACE) return false;

Powered by Google App Engine
This is Rietveld 408576698