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 00851ce644447916c1443d312584466cff3c601c..412c7e8e47ff228c31e80495d6685c0470e0a58a 100644 |
--- a/sdk/lib/_internal/compiler/implementation/dart_types.dart |
+++ b/sdk/lib/_internal/compiler/implementation/dart_types.dart |
@@ -28,6 +28,7 @@ class TypeKind { |
static const TypeKind TYPEDEF = const TypeKind('typedef'); |
static const TypeKind TYPE_VARIABLE = const TypeKind('type variable'); |
static const TypeKind MALFORMED_TYPE = const TypeKind('malformed'); |
+ static const TypeKind DYNAMIC = const TypeKind('dynamic'); |
static const TypeKind VOID = const TypeKind('void'); |
String toString() => id; |
@@ -101,10 +102,25 @@ abstract class DartType { |
bool get treatAsDynamic => false; |
/// Is [: true :] if this type is the dynamic type. |
- bool get isDynamic => false; |
+ bool get isDynamic => kind == TypeKind.DYNAMIC; |
/// Is [: true :] if this type is the void type. |
- bool get isVoid => false; |
+ bool get isVoid => kind == TypeKind.VOID; |
+ |
+ /// Is [: true :] if this type is an interface type. |
+ bool get isInterfaceType => kind == TypeKind.INTERFACE; |
+ |
+ /// Is [: true :] if this type is a typedef. |
+ bool get isTypedef => kind == TypeKind.TYPEDEF; |
+ |
+ /// Is [: true :] if this type is a function type. |
+ bool get isFunctionType => kind == TypeKind.FUNCTION; |
+ |
+ /// Is [: true :] if this type is a type variable. |
+ bool get isTypeVariable => kind == TypeKind.TYPE_VARIABLE; |
+ |
+ /// Is [: true :] if this type is a malformed type. |
+ bool get isMalformed => kind == TypeKind.MALFORMED_TYPE; |
/// Returns an occurrence of a type variable within this type, if any. |
TypeVariableType get typeVariableOccurrence => null; |
@@ -283,8 +299,6 @@ class VoidType extends DartType { |
return visitor.visitVoidType(this, argument); |
} |
- bool get isVoid => true; |
- |
String toString() => name; |
} |
@@ -581,8 +595,8 @@ class FunctionType extends DartType { |
factory FunctionType( |
FunctionTypedElement element, |
- DartType returnType, |
- [Link<DartType> parameterTypes = const Link<DartType>(), |
+ [DartType returnType = const DynamicType(), |
+ Link<DartType> parameterTypes = const Link<DartType>(), |
Link<DartType> optionalParameterTypes = const Link<DartType>(), |
Link<String> namedParameters = const Link<String>(), |
Link<DartType> namedParameterTypes = const Link<DartType>()]) { |
@@ -594,8 +608,8 @@ class FunctionType extends DartType { |
} |
factory FunctionType.synthesized( |
- DartType returnType, |
- [Link<DartType> parameterTypes = const Link<DartType>(), |
+ [DartType returnType = const DynamicType(), |
+ Link<DartType> parameterTypes = const Link<DartType>(), |
Link<DartType> optionalParameterTypes = const Link<DartType>(), |
Link<String> namedParameters = const Link<String>(), |
Link<DartType> namedParameterTypes = const Link<DartType>()]) { |
@@ -605,8 +619,8 @@ class FunctionType extends DartType { |
} |
FunctionType.internal(FunctionTypedElement this.element, |
- DartType this.returnType, |
- [this.parameterTypes = const Link<DartType>(), |
+ [DartType this.returnType = const DynamicType(), |
+ this.parameterTypes = const Link<DartType>(), |
this.optionalParameterTypes = const Link<DartType>(), |
this.namedParameters = const Link<String>(), |
this.namedParameterTypes = const Link<DartType>()]) { |
@@ -816,21 +830,28 @@ class TypedefType extends GenericType { |
} |
/** |
- * Special type to hold the [dynamic] type. Used for correctly returning |
- * 'dynamic' on [toString]. |
+ * Special type for the `dynamic` type. |
*/ |
-class DynamicType extends InterfaceType { |
- DynamicType(ClassElement element) : super(element); |
+class DynamicType extends DartType { |
+ const DynamicType(); |
+ |
+ Element get element => null; |
String get name => 'dynamic'; |
bool get treatAsDynamic => true; |
- bool get isDynamic => true; |
+ TypeKind get kind => TypeKind.DYNAMIC; |
+ |
+ DartType unalias(Compiler compiler) => this; |
+ |
+ DartType subst(Link<DartType> arguments, Link<DartType> parameters) => this; |
accept(DartTypeVisitor visitor, var argument) { |
return visitor.visitDynamicType(this, argument); |
} |
+ |
+ String toString() => name; |
} |
/** |
@@ -903,7 +924,7 @@ abstract class DartTypeVisitor<R, A> { |
visitGenericType(type, argument); |
R visitDynamicType(DynamicType type, A argument) => |
- visitInterfaceType(type, argument); |
+ visitType(type, argument); |
} |
/** |
@@ -911,10 +932,8 @@ abstract class DartTypeVisitor<R, A> { |
*/ |
abstract class AbstractTypeRelation extends DartTypeVisitor<bool, DartType> { |
final Compiler compiler; |
- final DynamicType dynamicType; |
- AbstractTypeRelation(Compiler this.compiler, |
- DynamicType this.dynamicType); |
+ AbstractTypeRelation(Compiler this.compiler); |
bool visitType(DartType t, DartType s) { |
throw 'internal error: unknown type kind ${t.kind}'; |
@@ -1089,9 +1108,7 @@ abstract class AbstractTypeRelation extends DartTypeVisitor<bool, DartType> { |
} |
class MoreSpecificVisitor extends AbstractTypeRelation { |
- MoreSpecificVisitor(Compiler compiler, |
- DynamicType dynamicType) |
- : super(compiler, dynamicType); |
+ MoreSpecificVisitor(Compiler compiler) : super(compiler); |
bool isMoreSpecific(DartType t, DartType s) { |
if (identical(t, s) || s.treatAsDynamic || |
@@ -1136,9 +1153,7 @@ class MoreSpecificVisitor extends AbstractTypeRelation { |
*/ |
class SubtypeVisitor extends MoreSpecificVisitor { |
- SubtypeVisitor(Compiler compiler, |
- DynamicType dynamicType) |
- : super(compiler, dynamicType); |
+ SubtypeVisitor(Compiler compiler) : super(compiler); |
bool isSubtype(DartType t, DartType s) { |
return t.treatAsDynamic || isMoreSpecific(t, s); |
@@ -1191,29 +1206,18 @@ typedef void CheckTypeVariableBound(GenericType type, |
class Types { |
final Compiler compiler; |
- final DynamicType dynamicType; |
final MoreSpecificVisitor moreSpecificVisitor; |
final SubtypeVisitor subtypeVisitor; |
final PotentialSubtypeVisitor potentialSubtypeVisitor; |
- factory Types(Compiler compiler, BaseClassElementX dynamicElement) { |
- DynamicType dynamicType = new DynamicType(dynamicElement); |
- dynamicElement.rawTypeCache = dynamicElement.thisTypeCache = dynamicType; |
- return new Types.internal(compiler, dynamicType); |
- } |
- |
- Types.internal(Compiler compiler, DynamicType dynamicType) |
+ Types(Compiler compiler) |
: this.compiler = compiler, |
- this.dynamicType = dynamicType, |
- this.moreSpecificVisitor = |
- new MoreSpecificVisitor(compiler, dynamicType), |
- this.subtypeVisitor = |
- new SubtypeVisitor(compiler, dynamicType), |
- this.potentialSubtypeVisitor = |
- new PotentialSubtypeVisitor(compiler, dynamicType); |
+ this.moreSpecificVisitor = new MoreSpecificVisitor(compiler), |
+ this.subtypeVisitor = new SubtypeVisitor(compiler), |
+ this.potentialSubtypeVisitor = new PotentialSubtypeVisitor(compiler); |
Types copy(Compiler compiler) { |
- return new Types.internal(compiler, dynamicType); |
+ return new Types(compiler); |
} |
/** Returns true if [t] is more specific than [s]. */ |
@@ -1339,10 +1343,10 @@ class Types { |
*/ |
static int compare(DartType a, DartType b) { |
if (a == b) return 0; |
- if (a.kind == TypeKind.VOID) { |
+ if (a.isVoid) { |
// [b] is not void => a < b. |
return -1; |
- } else if (b.kind == TypeKind.VOID) { |
+ } else if (b.isVoid) { |
// [a] is not void => a > b. |
return 1; |
} |
@@ -1354,21 +1358,21 @@ class Types { |
return 1; |
} |
bool isDefinedByDeclaration(DartType type) { |
- return type.kind == TypeKind.INTERFACE || |
- type.kind == TypeKind.TYPEDEF || |
- type.kind == TypeKind.TYPE_VARIABLE; |
+ return type.isInterfaceType || |
+ type.isTypedef || |
+ type.isTypeVariable; |
} |
if (isDefinedByDeclaration(a)) { |
if (isDefinedByDeclaration(b)) { |
int result = Elements.compareByPosition(a.element, b.element); |
if (result != 0) return result; |
- if (a.kind == TypeKind.TYPE_VARIABLE) { |
- return b.kind == TypeKind.TYPE_VARIABLE |
+ if (a.isTypeVariable) { |
+ return b.isTypeVariable |
? 0 |
: 1; // [b] is not a type variable => a > b. |
} else { |
- if (b.kind == TypeKind.TYPE_VARIABLE) { |
+ if (b.isTypeVariable) { |
// [a] is not a type variable => a < b. |
return -1; |
} else { |
@@ -1386,8 +1390,8 @@ class Types { |
// nor void => a > b. |
return 1; |
} |
- if (a.kind == TypeKind.FUNCTION) { |
- if (b.kind == TypeKind.FUNCTION) { |
+ if (a.isFunctionType) { |
+ if (b.isFunctionType) { |
FunctionType aFunc = a; |
FunctionType bFunc = b; |
int result = compare(aFunc.returnType, bFunc.returnType); |
@@ -1418,7 +1422,7 @@ class Types { |
// [b] is a malformed or statement type => a < b. |
return -1; |
} |
- } else if (b.kind == TypeKind.FUNCTION) { |
+ } else if (b.isFunctionType) { |
// [b] is a malformed or statement type => a > b. |
return 1; |
} |
@@ -1434,8 +1438,8 @@ class Types { |
// [a] is a malformed type => a < b. |
return -1; |
} |
- assert (a.kind == TypeKind.MALFORMED_TYPE); |
- assert (b.kind == TypeKind.MALFORMED_TYPE); |
+ assert (a.isMalformed); |
+ assert (b.isMalformed); |
// TODO(johnniwinther): Can we do this better? |
return Elements.compareByPosition(a.element, b.element); |
} |
@@ -1564,13 +1568,13 @@ class Types { |
DartType computeLeastUpperBoundTypeVariableTypes(DartType a, |
DartType b) { |
Set<DartType> typeVariableBounds = new Set<DartType>(); |
- while (a.kind == TypeKind.TYPE_VARIABLE) { |
+ while (a.isTypeVariable) { |
if (a == b) return a; |
typeVariableBounds.add(a); |
TypeVariableElement element = a.element; |
a = element.bound; |
} |
- while (b.kind == TypeKind.TYPE_VARIABLE) { |
+ while (b.isTypeVariable) { |
if (typeVariableBounds.contains(b)) return b; |
TypeVariableElement element = b.element; |
b = element.bound; |
@@ -1582,32 +1586,32 @@ class Types { |
DartType computeLeastUpperBound(DartType a, DartType b) { |
if (a == b) return a; |
- if (a.kind == TypeKind.TYPE_VARIABLE || |
- b.kind == TypeKind.TYPE_VARIABLE) { |
+ if (a.isTypeVariable || |
+ b.isTypeVariable) { |
return computeLeastUpperBoundTypeVariableTypes(a, b); |
} |
a = a.unalias(compiler); |
b = b.unalias(compiler); |
- if (a.treatAsDynamic || b.treatAsDynamic) return dynamicType; |
+ if (a.treatAsDynamic || b.treatAsDynamic) return const DynamicType(); |
if (a.isVoid || b.isVoid) return const VoidType(); |
- if (a.kind == TypeKind.FUNCTION && b.kind == TypeKind.FUNCTION) { |
+ if (a.isFunctionType && b.isFunctionType) { |
return computeLeastUpperBoundFunctionTypes(a, b); |
} |
- if (a.kind == TypeKind.FUNCTION) { |
+ if (a.isFunctionType) { |
a = compiler.functionClass.rawType; |
} |
- if (b.kind == TypeKind.FUNCTION) { |
+ if (b.isFunctionType) { |
b = compiler.functionClass.rawType; |
} |
- if (a.kind == TypeKind.INTERFACE && b.kind == TypeKind.INTERFACE) { |
+ if (a.isInterfaceType && b.isInterfaceType) { |
return computeLeastUpperBoundInterfaces(a, b); |
} |
- return dynamicType; |
+ return const DynamicType(); |
} |
} |
@@ -1617,10 +1621,7 @@ class Types { |
* [:false:] only if we are sure no such substitution exists. |
*/ |
class PotentialSubtypeVisitor extends SubtypeVisitor { |
- PotentialSubtypeVisitor(Compiler compiler, |
- DynamicType dynamicType) |
- : super(compiler, dynamicType); |
- |
+ PotentialSubtypeVisitor(Compiler compiler) : super(compiler); |
bool isSubtype(DartType t, DartType s) { |
if (t is TypeVariableType || s is TypeVariableType) { |
@@ -1656,7 +1657,7 @@ class MoreSpecificSubtypeVisitor extends DartTypeVisitor<bool, DartType> { |
constraintMap = new Map<TypeVariableType, DartType>(); |
element.typeVariables.forEach((TypeVariableType typeVariable) { |
- constraintMap[typeVariable] = compiler.types.dynamicType; |
+ constraintMap[typeVariable] = const DynamicType(); |
}); |
if (supertypeInstance.accept(this, supertype)) { |
LinkBuilder<DartType> typeArguments = new LinkBuilder<DartType>(); |