Index: pkg/compiler/lib/src/dart_types.dart |
diff --git a/pkg/compiler/lib/src/dart_types.dart b/pkg/compiler/lib/src/dart_types.dart |
index 353c00aeff95216dba4b6ee98601134957b9da7c..1a8128a37203df3844107ac40c5b15f10e0f266e 100644 |
--- a/pkg/compiler/lib/src/dart_types.dart |
+++ b/pkg/compiler/lib/src/dart_types.dart |
@@ -76,17 +76,27 @@ abstract class DartType { |
return subst(type.typeArguments, type.element.typeVariables); |
} |
- /** |
- * Returns the unaliased type of this type. |
- * |
- * The unaliased type of a typedef'd type is the unaliased type to which its |
- * name is bound. The unaliased version of any other type is the type itself. |
- * |
- * For example, the unaliased type of [: typedef A Func<A,B>(B b) :] is the |
- * function type [: (B) -> A :] and the unaliased type of |
- * [: Func<int,String> :] is the function type [: (String) -> int :]. |
- */ |
- DartType unalias(Resolution resolution); |
+ /// Computes the unaliased type of this type. |
+ /// |
+ /// The unaliased type of a typedef'd type is the unaliased type to which its |
+ /// name is bound. The unaliased version of any other type is the type itself. |
+ /// |
+ /// For example, the unaliased type of `typedef A Func<A,B>(B b)` is the |
+ /// function type `(B) -> A` and the unaliased type of `Func<int,String>` |
+ /// is the function type `(String) -> int`. |
+ // TODO(johnniwinther): Maybe move this to [TypedefType]. |
+ void computeUnaliased(Resolution resolution) {} |
+ |
+ |
+ /// Returns the unaliased type of this type. |
+ /// |
+ /// The unaliased type of a typedef'd type is the unaliased type to which its |
+ /// name is bound. The unaliased version of any other type is the type itself. |
+ /// |
+ /// For example, the unaliased type of `typedef A Func<A,B>(B b)` is the |
+ /// function type `(B) -> A` and the unaliased type of `Func<int,String>` |
+ /// is the function type `(String) -> int`. |
+ DartType get unaliased => this; |
/** |
* If this type is malformed or a generic type created with the wrong number |
@@ -219,8 +229,6 @@ class TypeVariableType extends DartType { |
return this; |
} |
- DartType unalias(Resolution resolution) => this; |
- |
TypeVariableType get typeVariableOccurrence => this; |
void forEachTypeVariable(f(TypeVariableType variable)) { |
@@ -253,8 +261,6 @@ class StatementType extends DartType { |
DartType subst(List<DartType> arguments, List<DartType> parameters) => this; |
- DartType unalias(Resolution resolution) => this; |
- |
accept(DartTypeVisitor visitor, var argument) { |
return visitor.visitStatementType(this, argument); |
} |
@@ -274,8 +280,6 @@ class VoidType extends DartType { |
return this; |
} |
- DartType unalias(Resolution resolution) => this; |
- |
accept(DartTypeVisitor visitor, var argument) { |
return visitor.visitVoidType(this, argument); |
} |
@@ -324,8 +328,6 @@ class MalformedType extends DartType { |
// Malformed types are treated as dynamic. |
bool get treatAsDynamic => true; |
- DartType unalias(Resolution resolution) => this; |
- |
accept(DartTypeVisitor visitor, var argument) { |
return visitor.visitMalformedType(this, argument); |
} |
@@ -491,8 +493,6 @@ class InterfaceType extends GenericType { |
return null; |
} |
- DartType unalias(Resolution resolution) => this; |
- |
MemberSignature lookupInterfaceMember(Name name) { |
MemberSignature member = element.lookupInterfaceMember(name); |
if (member != null && isGeneric) { |
@@ -660,8 +660,6 @@ class FunctionType extends DartType { |
return this; |
} |
- DartType unalias(Resolution resolution) => this; |
- |
TypeVariableType get typeVariableOccurrence { |
TypeVariableType typeVariableType = returnType.typeVariableOccurrence; |
if (typeVariableType != null) return typeVariableType; |
@@ -766,6 +764,8 @@ class FunctionType extends DartType { |
} |
class TypedefType extends GenericType { |
+ DartType _unaliased; |
+ |
TypedefType(TypedefElement element, |
[List<DartType> typeArguments = const <DartType>[]]) |
: super(element, typeArguments); |
@@ -785,11 +785,21 @@ class TypedefType extends GenericType { |
return new TypedefType(element, newTypeArguments); |
} |
- DartType unalias(Resolution resolution) { |
- element.ensureResolved(resolution); |
- element.checkCyclicReference(resolution); |
- DartType definition = element.alias.unalias(resolution); |
- return definition.substByContext(this); |
+ void computeUnaliased(Resolution resolution) { |
+ if (_unaliased == null) { |
+ element.ensureResolved(resolution); |
+ element.checkCyclicReference(resolution); |
+ element.alias.computeUnaliased(resolution); |
+ _unaliased = element.alias.unaliased.substByContext(this); |
+ } |
+ } |
+ |
+ DartType get unaliased { |
+ if (_unaliased == null) { |
+ DartType definition = element.alias.unaliased; |
+ _unaliased = definition.substByContext(this); |
+ } |
+ return _unaliased; |
} |
int get hashCode => super.hashCode; |
@@ -801,21 +811,6 @@ class TypedefType extends GenericType { |
} |
} |
-/// A typedef which has already been resolved to its alias. |
-class ResolvedTypedefType extends TypedefType { |
- FunctionType alias; |
- |
- ResolvedTypedefType(TypedefElement element, |
- List<DartType> typeArguments, |
- this.alias) |
- : super(element, typeArguments) { |
- assert(invariant(element, alias != null, |
- message: 'Alias must be non-null on $element.')); |
- } |
- |
- FunctionType unalias(Resolution resolution) => alias; |
-} |
- |
/** |
* Special type for the `dynamic` type. |
*/ |
@@ -830,8 +825,6 @@ class DynamicType extends DartType { |
TypeKind get kind => TypeKind.DYNAMIC; |
- DartType unalias(Resolution resolution) => this; |
- |
DartType subst(List<DartType> arguments, List<DartType> parameters) => this; |
accept(DartTypeVisitor visitor, var argument) { |
@@ -949,11 +942,11 @@ abstract class BaseDartTypeVisitor<R, A> extends DartTypeVisitor<R, A> { |
*/ |
abstract class AbstractTypeRelation |
extends BaseDartTypeVisitor<bool, DartType> { |
- final Compiler compiler; |
- CoreTypes get coreTypes => compiler.coreTypes; |
- Resolution get resolution => compiler.resolution; |
+ final Resolution resolution; |
+ |
+ AbstractTypeRelation(this.resolution); |
- AbstractTypeRelation(this.compiler); |
+ CoreTypes get coreTypes => resolution.coreTypes; |
bool visitType(DartType t, DartType s) { |
throw 'internal error: unknown type kind ${t.kind}'; |
@@ -1130,7 +1123,7 @@ abstract class AbstractTypeRelation |
} |
class MoreSpecificVisitor extends AbstractTypeRelation { |
- MoreSpecificVisitor(Compiler compiler) : super(compiler); |
+ MoreSpecificVisitor(Resolution resolution) : super(resolution); |
bool isMoreSpecific(DartType t, DartType s) { |
if (identical(t, s) || s.treatAsDynamic || t == coreTypes.nullType) { |
@@ -1145,8 +1138,10 @@ class MoreSpecificVisitor extends AbstractTypeRelation { |
if (s == coreTypes.objectType) { |
return true; |
} |
- t = t.unalias(resolution); |
- s = s.unalias(resolution); |
+ t.computeUnaliased(resolution); |
+ t = t.unaliased; |
+ s.computeUnaliased(resolution); |
+ s = s.unaliased; |
return t.accept(this, s); |
} |
@@ -1174,7 +1169,7 @@ class MoreSpecificVisitor extends AbstractTypeRelation { |
*/ |
class SubtypeVisitor extends MoreSpecificVisitor { |
- SubtypeVisitor(Compiler compiler) : super(compiler); |
+ SubtypeVisitor(Resolution resolution) : super(resolution); |
bool isSubtype(DartType t, DartType s) { |
return t.treatAsDynamic || isMoreSpecific(t, s); |
@@ -1237,26 +1232,23 @@ abstract class DartTypes { |
} |
class Types implements DartTypes { |
- // TODO(johnniwinther): Replace by [CoreTypes]. |
- final Compiler compiler; |
+ final Resolution resolution; |
final MoreSpecificVisitor moreSpecificVisitor; |
final SubtypeVisitor subtypeVisitor; |
final PotentialSubtypeVisitor potentialSubtypeVisitor; |
- CoreTypes get coreTypes => compiler.coreTypes; |
+ CoreTypes get coreTypes => resolution.coreTypes; |
- DiagnosticReporter get reporter => compiler.reporter; |
+ DiagnosticReporter get reporter => resolution.reporter; |
- Resolution get resolution => compiler.resolution; |
+ Types(Resolution resolution) |
+ : this.resolution = resolution, |
+ this.moreSpecificVisitor = new MoreSpecificVisitor(resolution), |
+ this.subtypeVisitor = new SubtypeVisitor(resolution), |
+ this.potentialSubtypeVisitor = new PotentialSubtypeVisitor(resolution); |
- Types(Compiler compiler) |
- : this.compiler = compiler, |
- this.moreSpecificVisitor = new MoreSpecificVisitor(compiler), |
- this.subtypeVisitor = new SubtypeVisitor(compiler), |
- this.potentialSubtypeVisitor = new PotentialSubtypeVisitor(compiler); |
- |
- Types copy(Compiler compiler) { |
- return new Types(compiler); |
+ Types copy(Resolution resolution) { |
+ return new Types(resolution); |
} |
/// Flatten [type] by recursively removing enclosing `Future` annotations. |
@@ -1290,15 +1282,13 @@ class Types implements DartTypes { |
return type; |
} |
- /** Returns true if [t] is more specific than [s]. */ |
+ /// Returns true if [t] is more specific than [s]. |
bool isMoreSpecific(DartType t, DartType s) { |
return moreSpecificVisitor.isMoreSpecific(t, s); |
} |
- /** |
- * Returns the most specific type of [t] and [s] or `null` if neither is more |
- * specific than the other. |
- */ |
+ /// Returns the most specific type of [t] and [s] or `null` if neither is more |
+ /// specific than the other. |
DartType getMostSpecific(DartType t, DartType s) { |
if (isMoreSpecific(t, s)) { |
return t; |
@@ -1644,13 +1634,14 @@ class Types implements DartTypes { |
DartType computeLeastUpperBound(DartType a, DartType b) { |
if (a == b) return a; |
- if (a.isTypeVariable || |
- b.isTypeVariable) { |
+ if (a.isTypeVariable || b.isTypeVariable) { |
return computeLeastUpperBoundTypeVariableTypes(a, b); |
} |
- a = a.unalias(resolution); |
- b = b.unalias(resolution); |
+ a.computeUnaliased(resolution); |
+ a = a.unaliased; |
+ b.computeUnaliased(resolution); |
+ b = b.unaliased; |
if (a.treatAsDynamic || b.treatAsDynamic) return const DynamicType(); |
if (a.isVoid || b.isVoid) return const VoidType(); |
@@ -1699,19 +1690,22 @@ class Types implements DartTypes { |
/// unaliasedBound(U) = unaliasedBound(Baz) = ()->dynamic |
/// unaliasedBound(X) = unaliasedBound(Y) = `Object` |
/// |
- static DartType computeUnaliasedBound(Compiler compiler, DartType type) { |
+ static DartType computeUnaliasedBound( |
+ Resolution resolution, |
+ DartType type) { |
DartType originalType = type; |
while (type.isTypeVariable) { |
TypeVariableType variable = type; |
type = variable.element.bound; |
if (type == originalType) { |
- type = compiler.objectClass.rawType; |
+ type = resolution.coreTypes.objectType; |
} |
} |
if (type.isMalformed) { |
return const DynamicType(); |
} |
- return type.unalias(compiler.resolution); |
+ type.computeUnaliased(resolution); |
+ return type.unaliased; |
} |
/// Computes the interface type of [type], which is the type that defines |
@@ -1741,13 +1735,15 @@ class Types implements DartTypes { |
/// When typechecking `o.foo` the interface type of the static type of `o` is |
/// used to lookup the existence and type of `foo`. |
/// |
- static InterfaceType computeInterfaceType(Compiler compiler, DartType type) { |
- type = computeUnaliasedBound(compiler, type); |
+ static InterfaceType computeInterfaceType( |
+ Resolution resolution, |
+ DartType type) { |
+ type = computeUnaliasedBound(resolution, type); |
if (type.treatAsDynamic) { |
return null; |
} |
if (type.isFunctionType) { |
- type = compiler.functionClass.rawType; |
+ type = resolution.coreTypes.functionType; |
} |
assert(invariant(NO_LOCATION_SPANNABLE, type.isInterfaceType, |
message: "unexpected type kind ${type.kind}.")); |
@@ -1761,7 +1757,7 @@ class Types implements DartTypes { |
* [:false:] only if we are sure no such substitution exists. |
*/ |
class PotentialSubtypeVisitor extends SubtypeVisitor { |
- PotentialSubtypeVisitor(Compiler compiler) : super(compiler); |
+ PotentialSubtypeVisitor(Resolution resolution) : super(resolution); |
bool isSubtype(DartType t, DartType s) { |
if (t is TypeVariableType || s is TypeVariableType) { |
@@ -1779,10 +1775,10 @@ class PotentialSubtypeVisitor extends SubtypeVisitor { |
/// constraints are too complex or the two types are too different, `false` |
/// is returned. Otherwise, the [constraintMap] holds the valid constraints. |
class MoreSpecificSubtypeVisitor extends BaseDartTypeVisitor<bool, DartType> { |
- final Compiler compiler; |
+ final Types types; |
Map<TypeVariableType, DartType> constraintMap; |
- MoreSpecificSubtypeVisitor(Compiler this.compiler); |
+ MoreSpecificSubtypeVisitor(this.types); |
/// Compute an instance of [element] which is more specific than [supertype]. |
/// If no instance is found, `null` is returned. |
@@ -1809,7 +1805,7 @@ class MoreSpecificSubtypeVisitor extends BaseDartTypeVisitor<bool, DartType> { |
} |
bool visitType(DartType type, DartType argument) { |
- return compiler.types.isMoreSpecific(type, argument); |
+ return types.isMoreSpecific(type, argument); |
} |
bool visitTypes(List<DartType> a, List<DartType> b) { |
@@ -1822,7 +1818,7 @@ class MoreSpecificSubtypeVisitor extends BaseDartTypeVisitor<bool, DartType> { |
bool visitTypeVariableType(TypeVariableType type, DartType argument) { |
DartType constraint = |
- compiler.types.getMostSpecific(constraintMap[type], argument); |
+ types.getMostSpecific(constraintMap[type], argument); |
constraintMap[type] = constraint; |
return constraint != null; |
} |