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 2d3ea949de2ca5e995fa3afea0c8065fb4d77009..a3e0821fa214fd7c6da7b96d7ce2cff181d9dc6e 100644 |
--- a/sdk/lib/_internal/compiler/implementation/dart_types.dart |
+++ b/sdk/lib/_internal/compiler/implementation/dart_types.dart |
@@ -81,43 +81,46 @@ abstract class DartType { |
Member lookupMember(SourceString name, {bool isSetter: false}) => null; |
/** |
- * A type is malformed if it is itself a malformed type or contains a |
- * malformed type. |
+ * If this type is malformed or a generic type created with the wrong number |
+ * of type arguments then [userProvidedBadType] holds the bad type provided |
+ * by the user. |
*/ |
- bool get isMalformed => false; |
- |
+ DartType get userProvidedBadType => null; |
+ |
+ /// Returns [:true:] if this type contains an ambiguous type. |
+ bool get containsAmbiguousTypes { |
+ return !forEachAmbiguousType((_) => false); |
+ } |
+ |
/** |
- * Calls [f] with each [MalformedType] within this type. |
+ * Calls [f] with each [AmbiguousType] within this type. |
* |
* If [f] returns [: false :], the traversal stops prematurely. |
* |
- * [forEachMalformedType] returns [: false :] if the traversal was stopped |
+ * [forEachAmbiguousType] returns [: false :] if the traversal was stopped |
* prematurely. |
*/ |
- bool forEachMalformedType(bool f(MalformedType type)) => true; |
+ bool forEachAmbiguousType(bool f(AmbiguousType type)) => true; |
- /** |
- * Is [: true :] if this type has no explict type arguments. |
- */ |
+ /// Is [: true :] if this type has no explict type arguments. |
bool get isRaw => true; |
+ /// Returns the raw version of this type. |
DartType asRaw() => this; |
- /** |
- * Is [: true :] if this type is the dynamic type. |
- */ |
+ /// Is [: true :] if this type should be treated as the dynamic type. |
+ bool get treatAsDynamic => false; |
+ |
+ /// Is [: true :] if this type is the dynamic type. |
bool get isDynamic => false; |
- /** |
- * Is [: true :] if this type is the void type. |
- */ |
+ /// Is [: true :] if this type is the void type. |
bool get isVoid => false; |
- /** |
- * Returns an occurrence of a type variable within this type, if any. |
- */ |
+ /// Returns an occurrence of a type variable within this type, if any. |
TypeVariableType get typeVariableOccurrence => null; |
+ /// Applies [f] to each occurence of a [TypeVariableType] within this type. |
void forEachTypeVariable(f(TypeVariableType variable)) {} |
TypeVariableType _findTypeVariableOccurrence(Link<DartType> types) { |
@@ -130,9 +133,7 @@ abstract class DartType { |
return null; |
} |
- /** |
- * Is [: true :] if this type contains any type variables. |
- */ |
+ /// Is [: true :] if this type contains any type variables. |
bool get containsTypeVariables => typeVariableOccurrence != null; |
accept(DartTypeVisitor visitor, var argument); |
@@ -334,9 +335,8 @@ class MalformedType extends DartType { |
return this; |
} |
- bool get isMalformed => true; |
- |
- bool forEachMalformedType(bool f(MalformedType type)) => f(this); |
+ // Malformed types are treated as dynamic. |
+ bool get treatAsDynamic => true; |
DartType unalias(Compiler compiler) => this; |
@@ -364,20 +364,18 @@ class MalformedType extends DartType { |
} |
} |
-bool hasMalformed(Link<DartType> types) { |
- for (DartType typeArgument in types) { |
- if (typeArgument.isMalformed) { |
- return true; |
- } |
- } |
- return false; |
+class AmbiguousType extends MalformedType { |
+ AmbiguousType(ErroneousElement element, |
+ [Link<DartType> typeArguments = null]) |
+ : super(element, null, typeArguments); |
+ |
+ bool forEachAmbiguousType(bool f(AmbiguousType type)) => f(this); |
} |
abstract class GenericType extends DartType { |
final Link<DartType> typeArguments; |
- final bool isMalformed; |
- GenericType(Link<DartType> this.typeArguments, bool this.isMalformed); |
+ GenericType(Link<DartType> this.typeArguments); |
TypeDeclarationElement get element; |
@@ -403,9 +401,9 @@ abstract class GenericType extends DartType { |
return this; |
} |
- bool forEachMalformedType(bool f(MalformedType type)) { |
+ bool forEachAmbiguousType(bool f(AmbiguousType type)) { |
for (DartType typeArgument in typeArguments) { |
- if (!typeArgument.forEachMalformedType(f)) { |
+ if (!typeArgument.forEachAmbiguousType(f)) { |
return false; |
} |
} |
@@ -465,7 +463,7 @@ class InterfaceType extends GenericType { |
InterfaceType(this.element, |
[Link<DartType> typeArguments = const Link<DartType>()]) |
- : super(typeArguments, hasMalformed(typeArguments)) { |
+ : super(typeArguments) { |
assert(invariant(element, element.isDeclaration)); |
assert(invariant(element, element.thisType == null || |
typeArguments.slowLength() == element.typeVariables.slowLength(), |
@@ -473,10 +471,10 @@ class InterfaceType extends GenericType { |
'Provided type arguments: $typeArguments.')); |
} |
- InterfaceType.userProvidedBadType(this.element, |
- [Link<DartType> typeArguments = |
- const Link<DartType>()]) |
- : super(typeArguments, true); |
+ InterfaceType.forUserProvidedBadType(this.element, |
+ [Link<DartType> typeArguments = |
+ const Link<DartType>()]) |
+ : super(typeArguments); |
TypeKind get kind => TypeKind.INTERFACE; |
@@ -575,6 +573,43 @@ class InterfaceType extends GenericType { |
} |
} |
+/** |
+ * Special subclass of [InterfaceType] used for generic interface types created |
+ * with the wrong number of type arguments. |
+ * |
+ * The type uses [:dynamic:] for all it s type arguments. |
+ */ |
+class BadInterfaceType extends InterfaceType { |
+ final InterfaceType userProvidedBadType; |
+ |
+ BadInterfaceType(ClassElement element, |
+ InterfaceType this.userProvidedBadType) |
+ : super(element, element.rawType.typeArguments); |
+ |
+ String toString() { |
+ return userProvidedBadType.toString(); |
+ } |
+} |
+ |
+ |
+/** |
+ * Special subclass of [TypedefType] used for generic typedef types created |
+ * with the wrong number of type arguments. |
+ * |
+ * The type uses [:dynamic:] for all it s type arguments. |
+ */ |
+class BadTypedefType extends TypedefType { |
+ final TypedefType userProvidedBadType; |
+ |
+ BadTypedefType(TypedefElement element, |
+ TypedefType this.userProvidedBadType) |
+ : super(element, element.rawType.typeArguments); |
+ |
+ String toString() { |
+ return userProvidedBadType.toString(); |
+ } |
+} |
+ |
class FunctionType extends DartType { |
final Element element; |
final DartType returnType; |
@@ -591,38 +626,13 @@ class FunctionType extends DartType { |
* [namedParameters]. |
*/ |
final Link<DartType> namedParameterTypes; |
- final bool isMalformed; |
- |
- factory FunctionType(Element element, |
- DartType returnType, |
- Link<DartType> parameterTypes, |
- Link<DartType> optionalParameterTypes, |
- Link<SourceString> namedParameters, |
- Link<DartType> namedParameterTypes) { |
- // Compute [isMalformed] eagerly since it is faster than a lazy computation |
- // and since [isMalformed] most likely will be accessed in [Types.isSubtype] |
- // anyway. |
- bool isMalformed = returnType != null && |
- returnType.isMalformed || |
- hasMalformed(parameterTypes) || |
- hasMalformed(optionalParameterTypes) || |
- hasMalformed(namedParameterTypes); |
- return new FunctionType.internal(element, |
- returnType, |
- parameterTypes, |
- optionalParameterTypes, |
- namedParameters, |
- namedParameterTypes, |
- isMalformed); |
- } |
- |
- FunctionType.internal(Element this.element, |
- DartType this.returnType, |
- Link<DartType> this.parameterTypes, |
- Link<DartType> this.optionalParameterTypes, |
- Link<SourceString> this.namedParameters, |
- Link<DartType> this.namedParameterTypes, |
- bool this.isMalformed) { |
+ |
+ FunctionType(Element this.element, |
+ DartType this.returnType, |
+ Link<DartType> this.parameterTypes, |
+ Link<DartType> this.optionalParameterTypes, |
+ Link<SourceString> this.namedParameters, |
+ Link<DartType> this.namedParameterTypes) { |
assert(invariant(element, element.isDeclaration)); |
// Assert that optional and named parameters are not used at the same time. |
assert(optionalParameterTypes.isEmpty || namedParameterTypes.isEmpty); |
@@ -676,22 +686,22 @@ class FunctionType extends DartType { |
return this; |
} |
- bool forEachMalformedType(bool f(MalformedType type)) { |
- if (!returnType.forEachMalformedType(f)) { |
+ bool forEachAmbiguousType(bool f(AmbiguousType type)) { |
+ if (!returnType.forEachAmbiguousType(f)) { |
return false; |
} |
for (DartType parameterType in parameterTypes) { |
- if (!parameterType.forEachMalformedType(f)) { |
+ if (!parameterType.forEachAmbiguousType(f)) { |
return false; |
} |
} |
for (DartType parameterType in optionalParameterTypes) { |
- if (!parameterType.forEachMalformedType(f)) { |
+ if (!parameterType.forEachAmbiguousType(f)) { |
return false; |
} |
} |
for (DartType parameterType in namedParameterTypes) { |
- if (!parameterType.forEachMalformedType(f)) { |
+ if (!parameterType.forEachAmbiguousType(f)) { |
return false; |
} |
} |
@@ -805,16 +815,16 @@ class TypedefType extends GenericType { |
// match, like for [InterfaceType]. |
TypedefType(this.element, |
[Link<DartType> typeArguments = const Link<DartType>()]) |
- : super(typeArguments, hasMalformed(typeArguments)); |
+ : super(typeArguments); |
TypedefType _createType(Link<DartType> newTypeArguments) { |
return new TypedefType(element, newTypeArguments); |
} |
- TypedefType.userProvidedBadType(this.element, |
- [Link<DartType> typeArguments = |
- const Link<DartType>()]) |
- : super(typeArguments, true); |
+ TypedefType.forUserProvidedBadType(this.element, |
+ [Link<DartType> typeArguments = |
+ const Link<DartType>()]) |
+ : super(typeArguments); |
TypeKind get kind => TypeKind.TYPEDEF; |
@@ -846,6 +856,8 @@ class DynamicType extends InterfaceType { |
SourceString get name => const SourceString('dynamic'); |
+ bool get treatAsDynamic => true; |
+ |
bool get isDynamic => true; |
accept(DartTypeVisitor visitor, var argument) { |
@@ -976,10 +988,8 @@ class SubtypeVisitor extends DartTypeVisitor<bool, DartType> { |
bool isSubtype(DartType t, DartType s) { |
if (identical(t, s) || |
- identical(t, dynamicType) || |
- identical(s, dynamicType) || |
- t.isMalformed || |
- s.isMalformed || |
+ t.treatAsDynamic || |
+ s.treatAsDynamic || |
identical(s.element, compiler.objectClass) || |
identical(t.element, compiler.nullClass)) { |
return true; |
@@ -1229,14 +1239,15 @@ class Types { |
} |
/** |
- * Combine error messages in a malformed type to a single message string. |
+ * Combine error messages in a type containing ambiguous types to a single |
+ * message string. |
*/ |
- static String fetchReasonsFromMalformedType(DartType type) { |
+ static String fetchReasonsFromAmbiguousType(DartType type) { |
// TODO(johnniwinther): Figure out how to produce good error message in face |
// of multiple errors, and how to ensure non-localized error messages. |
var reasons = new List<String>(); |
- type.forEachMalformedType((MalformedType malformedType) { |
- ErroneousElement error = malformedType.element; |
+ type.forEachAmbiguousType((AmbiguousType ambiguousType) { |
+ ErroneousElement error = ambiguousType.element; |
Message message = error.messageKind.message(error.messageArguments); |
reasons.add(message.toString()); |
return true; |