Index: sdk/lib/_internal/compiler/implementation/dart_types.dart |
diff --git a/sdk/lib/_internal/compiler/implementation/dart_types.dart b/sdk/lib/_internal/compiler/implementation/dart_types.dart |
index bcec9216fd829498ade4442538813988b38e116b..d4fc525d28216003981ff210eb1e833b5572ca2e 100644 |
--- a/sdk/lib/_internal/compiler/implementation/dart_types.dart |
+++ b/sdk/lib/_internal/compiler/implementation/dart_types.dart |
@@ -908,6 +908,8 @@ class Member { |
} |
abstract class DartTypeVisitor<R, A> { |
+ const DartTypeVisitor(); |
+ |
R visitType(DartType type, A argument); |
R visitVoidType(VoidType type, A argument) => |
@@ -938,6 +940,9 @@ abstract class DartTypeVisitor<R, A> { |
visitInterfaceType(type, argument); |
} |
+/** |
+ * Type visitor that determines the subtype relation two types. |
+ */ |
class SubtypeVisitor extends DartTypeVisitor<bool, DartType> { |
final Compiler compiler; |
final DynamicType dynamicType; |
@@ -1140,6 +1145,7 @@ class Types { |
final VoidType voidType; |
final DynamicType dynamicType; |
final SubtypeVisitor subtypeVisitor; |
+ final PotentialSubtypeVisitor potentialSubtypeVisitor; |
factory Types(Compiler compiler, BaseClassElementX dynamicElement) { |
LibraryElement library = new LibraryElementX(new Script(null, null)); |
@@ -1148,11 +1154,15 @@ class Types { |
dynamicElement.rawTypeCache = dynamicElement.thisType = dynamicType; |
SubtypeVisitor subtypeVisitor = |
new SubtypeVisitor(compiler, dynamicType, voidType); |
- return new Types.internal(compiler, voidType, dynamicType, subtypeVisitor); |
+ PotentialSubtypeVisitor potentialSubtypeVisitor = |
+ new PotentialSubtypeVisitor(compiler, dynamicType, voidType); |
+ |
+ return new Types.internal(compiler, voidType, dynamicType, |
+ subtypeVisitor, potentialSubtypeVisitor); |
} |
Types.internal(this.compiler, this.voidType, this.dynamicType, |
- this.subtypeVisitor); |
+ this.subtypeVisitor, this.potentialSubtypeVisitor); |
/** Returns true if t is a subtype of s */ |
bool isSubtype(DartType t, DartType s) { |
@@ -1163,6 +1173,11 @@ class Types { |
return subtypeVisitor.isAssignable(r, s); |
} |
+ bool isPotentialSubtype(DartType t, DartType s) { |
+ // TODO(johnniwinther): Return a set of variable points in the positive |
+ // cases. |
+ return potentialSubtypeVisitor.isSubtype(t, s); |
+ } |
/** |
* Helper method for performing substitution of a linked list of types. |
@@ -1217,3 +1232,23 @@ class Types { |
return typeVariable.element.enclosingElement; |
} |
} |
+ |
+/** |
+ * Type visitor that determines one type could a subtype of another given the |
+ * right type variable substitution. The computation is approximate and returns |
+ * [:false:] only if we are sure no such substitution exists. |
+ */ |
+class PotentialSubtypeVisitor extends SubtypeVisitor { |
+ PotentialSubtypeVisitor(Compiler compiler, |
+ DynamicType dynamicType, |
+ VoidType voidType) |
+ : super(compiler, dynamicType, voidType); |
+ |
+ |
+ bool isSubtype(DartType t, DartType s) { |
+ if (t is TypeVariableType || s is TypeVariableType) { |
+ return true; |
+ } |
+ return super.isSubtype(t, s); |
+ } |
+} |