Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/typechecker.dart |
| diff --git a/sdk/lib/_internal/compiler/implementation/typechecker.dart b/sdk/lib/_internal/compiler/implementation/typechecker.dart |
| index f3a0dcbfabc50ac940ca173d06f83e43616f2165..99709a52627aacaf43f0320853989ad912a3435e 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/typechecker.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/typechecker.dart |
| @@ -85,6 +85,22 @@ abstract class DartType { |
| */ |
| DartType unalias(Compiler compiler); |
| + /** |
| + * A type is malformed if it is itself a malformed type or contains a |
| + * malformed type. |
| + */ |
| + bool get isMalformed => false; |
| + |
| + /** |
| + * Calls [f] with each [MalformedType] within this type. |
| + * |
| + * If [f] returns [: false :], the traversal stops prematurely. |
| + * |
| + * [forEachMalformedType] returns [: false :] if the traversal was stopped |
| + * prematurely. |
| + */ |
| + bool forEachMalformedType(bool f(MalformedType type)) => true; |
| + |
| bool operator ==(other); |
| /** |
| @@ -251,23 +267,66 @@ Link<DartType> substTypes(Link<DartType> types, |
| } |
| class MalformedType extends DartType { |
| - const MalformedType(this.element); |
| + final Element element; |
| + |
| + /** |
| + * [declaredType] holds the type which declared this malformed type. |
|
ahe
2012/11/30 15:44:07
... holds the type which the user wrote in code.
Johnni Winther
2012/12/04 10:07:17
Done.
|
| + * |
| + * For instance, for the malformed type for [: Map<String> :] the |
| + * [declaredType] is [: Map<String> :]. |
| + */ |
| + final DartType declaredType; |
|
ahe
2012/11/30 15:44:07
Rename to userProvidedBadType?
Johnni Winther
2012/12/04 10:07:17
Done.
|
| + |
| + /** |
| + * Type arguments for the malformed typed, if these cannot fit in the |
| + * [declaredType]. |
| + * |
| + * This field is for instance used for [: dynamic<int> :] and [: T<int> :] |
| + * where [: T :] is a type variable, in which case [declaredType] holds |
| + * [: dynamic :] and [: T :], respectively, or for [: X<int> :] where [: X :] |
| + * is not resolved or does not imply a type. |
| + */ |
| + final Link<DartType> typeArguments; |
| + |
| + MalformedType(this.element, this.declaredType, |
| + [this.typeArguments = null]); |
|
ahe
2012/11/30 15:44:07
Need to be optional?
Johnni Winther
2012/12/04 10:07:17
I like it to be. It feels strange having to pass a
|
| TypeKind get kind => TypeKind.MALFORMED_TYPE; |
| SourceString get name => element.name; |
| - final MalformedTypeElement element; |
| + DartType subst(Link<DartType> arguments, Link<DartType> parameters) { |
| + // Malformed types are not substitutable. |
| + return this; |
| + } |
| - DartType unalias(Compiler compiler) => this; |
| + bool get isMalformed => true; |
| - int get hashCode => 1733; |
| + bool forEachMalformedType(bool f(MalformedType type)) => f(this); |
| - bool operator ==(other) => other is MalformedType; |
| + DartType unalias(Compiler compiler) => this; |
| - String toString() => name.slowToString(); |
| + String toString() { |
| + var sb = new StringBuffer(); |
| + if (typeArguments != null) { |
| + if (declaredType != null) { |
| + sb.add(declaredType.name.slowToString()); |
| + } else { |
| + sb.add(element.name.slowToString()); |
| + } |
| + if (!typeArguments.isEmpty) { |
| + sb.add('<'); |
| + typeArguments.printOn(sb, ', '); |
| + sb.add('>'); |
| + } |
| + } else { |
| + sb.add(declaredType.toString()); |
| + } |
| + return sb.toString(); |
| + } |
| } |
| +// TODO(johnniwinther): Add common supertype for InterfaceType and TypedefType. |
| class InterfaceType extends DartType { |
| final ClassElement element; |
| final Link<DartType> typeArguments; |
| @@ -300,6 +359,24 @@ class InterfaceType extends DartType { |
| return this; |
| } |
| + bool get isMalformed { |
|
ahe
2012/11/30 15:44:07
I'm worried about performance of this method.
Johnni Winther
2012/12/04 10:07:17
Changed to computed a creation time.
|
| + for (DartType typeArgument in typeArguments) { |
| + if (typeArgument.isMalformed) { |
| + return true; |
| + } |
| + } |
| + return false; |
| + } |
| + |
| + bool forEachMalformedType(bool f(MalformedType type)) { |
| + for (DartType typeArgument in typeArguments) { |
| + if (!typeArgument.forEachMalformedType(f)) { |
| + return false; |
| + } |
| + } |
| + return true; |
| + } |
| + |
| DartType unalias(Compiler compiler) => this; |
| String toString() { |
| @@ -366,6 +443,30 @@ class FunctionType extends DartType { |
| return this; |
| } |
| + bool get isMalformed { |
|
ahe
2012/11/30 15:44:07
Ditto.
Johnni Winther
2012/12/04 10:07:17
Changed to computed a creation time.
|
| + if (returnType.isMalformed) { |
| + return true; |
| + } |
| + for (DartType parameterType in parameterTypes) { |
| + if (parameterType.isMalformed) { |
| + return true; |
| + } |
| + } |
| + return false; |
| + } |
| + |
| + bool forEachMalformedType(bool f(MalformedType type)) { |
| + if (!returnType.forEachMalformedType(f)) { |
| + return false; |
| + } |
| + for (DartType parameterType in parameterTypes) { |
| + if (!parameterType.forEachMalformedType(f)) { |
| + return false; |
| + } |
| + } |
| + return true; |
| + } |
| + |
| DartType unalias(Compiler compiler) => this; |
| String toString() { |
| @@ -439,6 +540,24 @@ class TypedefType extends DartType { |
| return this; |
| } |
| + bool get isMalformed { |
|
ahe
2012/11/30 15:44:07
Ditto.
Johnni Winther
2012/12/04 10:07:17
Changed to computed a creation time.
|
| + for (DartType typeArgument in typeArguments) { |
| + if (typeArgument.isMalformed) { |
| + return true; |
| + } |
| + } |
| + return false; |
| + } |
| + |
| + bool forEachMalformedType(bool f(MalformedType type)) { |
| + for (DartType typeArgument in typeArguments) { |
| + if (!typeArgument.forEachMalformedType(f)) { |
| + return false; |
| + } |
| + } |
| + return true; |
| + } |
| + |
| DartType unalias(Compiler compiler) { |
| // TODO(ahe): This should be [ensureResolved]. |
| compiler.resolveTypedef(element); |
| @@ -477,10 +596,9 @@ class TypedefType extends DartType { |
| class DynamicType extends InterfaceType { |
| DynamicType(ClassElement element) : super(element); |
| - String toString() => 'dynamic'; |
| + SourceString get name => const SourceString('dynamic'); |
| } |
| - |
| class Types { |
| final Compiler compiler; |
| // TODO(karlklose): should we have a class Void? |
| @@ -504,6 +622,8 @@ class Types { |
| if (identical(t, s) || |
| identical(t, dynamicType) || |
| identical(s, dynamicType) || |
| + t.isMalformed || |
|
ahe
2012/11/30 15:44:07
Ditto.
Johnni Winther
2012/12/04 10:07:17
Done.
|
| + s.isMalformed || |
| identical(s.element, compiler.objectClass) || |
| identical(t.element, compiler.nullClass)) { |
| return true; |
| @@ -513,10 +633,6 @@ class Types { |
| if (t is VoidType) { |
| return false; |
| - } else if (t is MalformedType || s is MalformedType) { |
| - // TODO(johnniwinther): Malformed types should be treated as dynamic and |
| - // thus return true here. |
| - return false; |
| } else if (t is InterfaceType) { |
| if (s is !InterfaceType) return false; |
| ClassElement tc = t.element; |