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