| 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>();
|
|
|