Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(259)

Unified Diff: sdk/lib/_internal/compiler/implementation/dart_types.dart

Issue 19097003: Support new malformed types semantics. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix unittests. Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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;

Powered by Google App Engine
This is Rietveld 408576698