| Index: pkg/compiler/lib/src/dart_types.dart
|
| diff --git a/pkg/compiler/lib/src/dart_types.dart b/pkg/compiler/lib/src/dart_types.dart
|
| index 353c00aeff95216dba4b6ee98601134957b9da7c..1a8128a37203df3844107ac40c5b15f10e0f266e 100644
|
| --- a/pkg/compiler/lib/src/dart_types.dart
|
| +++ b/pkg/compiler/lib/src/dart_types.dart
|
| @@ -76,17 +76,27 @@ abstract class DartType {
|
| return subst(type.typeArguments, type.element.typeVariables);
|
| }
|
|
|
| - /**
|
| - * Returns the unaliased type of this type.
|
| - *
|
| - * The unaliased type of a typedef'd type is the unaliased type to which its
|
| - * name is bound. The unaliased version of any other type is the type itself.
|
| - *
|
| - * For example, the unaliased type of [: typedef A Func<A,B>(B b) :] is the
|
| - * function type [: (B) -> A :] and the unaliased type of
|
| - * [: Func<int,String> :] is the function type [: (String) -> int :].
|
| - */
|
| - DartType unalias(Resolution resolution);
|
| + /// Computes the unaliased type of this type.
|
| + ///
|
| + /// The unaliased type of a typedef'd type is the unaliased type to which its
|
| + /// name is bound. The unaliased version of any other type is the type itself.
|
| + ///
|
| + /// For example, the unaliased type of `typedef A Func<A,B>(B b)` is the
|
| + /// function type `(B) -> A` and the unaliased type of `Func<int,String>`
|
| + /// is the function type `(String) -> int`.
|
| + // TODO(johnniwinther): Maybe move this to [TypedefType].
|
| + void computeUnaliased(Resolution resolution) {}
|
| +
|
| +
|
| + /// Returns the unaliased type of this type.
|
| + ///
|
| + /// The unaliased type of a typedef'd type is the unaliased type to which its
|
| + /// name is bound. The unaliased version of any other type is the type itself.
|
| + ///
|
| + /// For example, the unaliased type of `typedef A Func<A,B>(B b)` is the
|
| + /// function type `(B) -> A` and the unaliased type of `Func<int,String>`
|
| + /// is the function type `(String) -> int`.
|
| + DartType get unaliased => this;
|
|
|
| /**
|
| * If this type is malformed or a generic type created with the wrong number
|
| @@ -219,8 +229,6 @@ class TypeVariableType extends DartType {
|
| return this;
|
| }
|
|
|
| - DartType unalias(Resolution resolution) => this;
|
| -
|
| TypeVariableType get typeVariableOccurrence => this;
|
|
|
| void forEachTypeVariable(f(TypeVariableType variable)) {
|
| @@ -253,8 +261,6 @@ class StatementType extends DartType {
|
|
|
| DartType subst(List<DartType> arguments, List<DartType> parameters) => this;
|
|
|
| - DartType unalias(Resolution resolution) => this;
|
| -
|
| accept(DartTypeVisitor visitor, var argument) {
|
| return visitor.visitStatementType(this, argument);
|
| }
|
| @@ -274,8 +280,6 @@ class VoidType extends DartType {
|
| return this;
|
| }
|
|
|
| - DartType unalias(Resolution resolution) => this;
|
| -
|
| accept(DartTypeVisitor visitor, var argument) {
|
| return visitor.visitVoidType(this, argument);
|
| }
|
| @@ -324,8 +328,6 @@ class MalformedType extends DartType {
|
| // Malformed types are treated as dynamic.
|
| bool get treatAsDynamic => true;
|
|
|
| - DartType unalias(Resolution resolution) => this;
|
| -
|
| accept(DartTypeVisitor visitor, var argument) {
|
| return visitor.visitMalformedType(this, argument);
|
| }
|
| @@ -491,8 +493,6 @@ class InterfaceType extends GenericType {
|
| return null;
|
| }
|
|
|
| - DartType unalias(Resolution resolution) => this;
|
| -
|
| MemberSignature lookupInterfaceMember(Name name) {
|
| MemberSignature member = element.lookupInterfaceMember(name);
|
| if (member != null && isGeneric) {
|
| @@ -660,8 +660,6 @@ class FunctionType extends DartType {
|
| return this;
|
| }
|
|
|
| - DartType unalias(Resolution resolution) => this;
|
| -
|
| TypeVariableType get typeVariableOccurrence {
|
| TypeVariableType typeVariableType = returnType.typeVariableOccurrence;
|
| if (typeVariableType != null) return typeVariableType;
|
| @@ -766,6 +764,8 @@ class FunctionType extends DartType {
|
| }
|
|
|
| class TypedefType extends GenericType {
|
| + DartType _unaliased;
|
| +
|
| TypedefType(TypedefElement element,
|
| [List<DartType> typeArguments = const <DartType>[]])
|
| : super(element, typeArguments);
|
| @@ -785,11 +785,21 @@ class TypedefType extends GenericType {
|
| return new TypedefType(element, newTypeArguments);
|
| }
|
|
|
| - DartType unalias(Resolution resolution) {
|
| - element.ensureResolved(resolution);
|
| - element.checkCyclicReference(resolution);
|
| - DartType definition = element.alias.unalias(resolution);
|
| - return definition.substByContext(this);
|
| + void computeUnaliased(Resolution resolution) {
|
| + if (_unaliased == null) {
|
| + element.ensureResolved(resolution);
|
| + element.checkCyclicReference(resolution);
|
| + element.alias.computeUnaliased(resolution);
|
| + _unaliased = element.alias.unaliased.substByContext(this);
|
| + }
|
| + }
|
| +
|
| + DartType get unaliased {
|
| + if (_unaliased == null) {
|
| + DartType definition = element.alias.unaliased;
|
| + _unaliased = definition.substByContext(this);
|
| + }
|
| + return _unaliased;
|
| }
|
|
|
| int get hashCode => super.hashCode;
|
| @@ -801,21 +811,6 @@ class TypedefType extends GenericType {
|
| }
|
| }
|
|
|
| -/// A typedef which has already been resolved to its alias.
|
| -class ResolvedTypedefType extends TypedefType {
|
| - FunctionType alias;
|
| -
|
| - ResolvedTypedefType(TypedefElement element,
|
| - List<DartType> typeArguments,
|
| - this.alias)
|
| - : super(element, typeArguments) {
|
| - assert(invariant(element, alias != null,
|
| - message: 'Alias must be non-null on $element.'));
|
| - }
|
| -
|
| - FunctionType unalias(Resolution resolution) => alias;
|
| -}
|
| -
|
| /**
|
| * Special type for the `dynamic` type.
|
| */
|
| @@ -830,8 +825,6 @@ class DynamicType extends DartType {
|
|
|
| TypeKind get kind => TypeKind.DYNAMIC;
|
|
|
| - DartType unalias(Resolution resolution) => this;
|
| -
|
| DartType subst(List<DartType> arguments, List<DartType> parameters) => this;
|
|
|
| accept(DartTypeVisitor visitor, var argument) {
|
| @@ -949,11 +942,11 @@ abstract class BaseDartTypeVisitor<R, A> extends DartTypeVisitor<R, A> {
|
| */
|
| abstract class AbstractTypeRelation
|
| extends BaseDartTypeVisitor<bool, DartType> {
|
| - final Compiler compiler;
|
| - CoreTypes get coreTypes => compiler.coreTypes;
|
| - Resolution get resolution => compiler.resolution;
|
| + final Resolution resolution;
|
| +
|
| + AbstractTypeRelation(this.resolution);
|
|
|
| - AbstractTypeRelation(this.compiler);
|
| + CoreTypes get coreTypes => resolution.coreTypes;
|
|
|
| bool visitType(DartType t, DartType s) {
|
| throw 'internal error: unknown type kind ${t.kind}';
|
| @@ -1130,7 +1123,7 @@ abstract class AbstractTypeRelation
|
| }
|
|
|
| class MoreSpecificVisitor extends AbstractTypeRelation {
|
| - MoreSpecificVisitor(Compiler compiler) : super(compiler);
|
| + MoreSpecificVisitor(Resolution resolution) : super(resolution);
|
|
|
| bool isMoreSpecific(DartType t, DartType s) {
|
| if (identical(t, s) || s.treatAsDynamic || t == coreTypes.nullType) {
|
| @@ -1145,8 +1138,10 @@ class MoreSpecificVisitor extends AbstractTypeRelation {
|
| if (s == coreTypes.objectType) {
|
| return true;
|
| }
|
| - t = t.unalias(resolution);
|
| - s = s.unalias(resolution);
|
| + t.computeUnaliased(resolution);
|
| + t = t.unaliased;
|
| + s.computeUnaliased(resolution);
|
| + s = s.unaliased;
|
|
|
| return t.accept(this, s);
|
| }
|
| @@ -1174,7 +1169,7 @@ class MoreSpecificVisitor extends AbstractTypeRelation {
|
| */
|
| class SubtypeVisitor extends MoreSpecificVisitor {
|
|
|
| - SubtypeVisitor(Compiler compiler) : super(compiler);
|
| + SubtypeVisitor(Resolution resolution) : super(resolution);
|
|
|
| bool isSubtype(DartType t, DartType s) {
|
| return t.treatAsDynamic || isMoreSpecific(t, s);
|
| @@ -1237,26 +1232,23 @@ abstract class DartTypes {
|
| }
|
|
|
| class Types implements DartTypes {
|
| - // TODO(johnniwinther): Replace by [CoreTypes].
|
| - final Compiler compiler;
|
| + final Resolution resolution;
|
| final MoreSpecificVisitor moreSpecificVisitor;
|
| final SubtypeVisitor subtypeVisitor;
|
| final PotentialSubtypeVisitor potentialSubtypeVisitor;
|
|
|
| - CoreTypes get coreTypes => compiler.coreTypes;
|
| + CoreTypes get coreTypes => resolution.coreTypes;
|
|
|
| - DiagnosticReporter get reporter => compiler.reporter;
|
| + DiagnosticReporter get reporter => resolution.reporter;
|
|
|
| - Resolution get resolution => compiler.resolution;
|
| + Types(Resolution resolution)
|
| + : this.resolution = resolution,
|
| + this.moreSpecificVisitor = new MoreSpecificVisitor(resolution),
|
| + this.subtypeVisitor = new SubtypeVisitor(resolution),
|
| + this.potentialSubtypeVisitor = new PotentialSubtypeVisitor(resolution);
|
|
|
| - Types(Compiler compiler)
|
| - : this.compiler = compiler,
|
| - this.moreSpecificVisitor = new MoreSpecificVisitor(compiler),
|
| - this.subtypeVisitor = new SubtypeVisitor(compiler),
|
| - this.potentialSubtypeVisitor = new PotentialSubtypeVisitor(compiler);
|
| -
|
| - Types copy(Compiler compiler) {
|
| - return new Types(compiler);
|
| + Types copy(Resolution resolution) {
|
| + return new Types(resolution);
|
| }
|
|
|
| /// Flatten [type] by recursively removing enclosing `Future` annotations.
|
| @@ -1290,15 +1282,13 @@ class Types implements DartTypes {
|
| return type;
|
| }
|
|
|
| - /** Returns true if [t] is more specific than [s]. */
|
| + /// Returns true if [t] is more specific than [s].
|
| bool isMoreSpecific(DartType t, DartType s) {
|
| return moreSpecificVisitor.isMoreSpecific(t, s);
|
| }
|
|
|
| - /**
|
| - * Returns the most specific type of [t] and [s] or `null` if neither is more
|
| - * specific than the other.
|
| - */
|
| + /// Returns the most specific type of [t] and [s] or `null` if neither is more
|
| + /// specific than the other.
|
| DartType getMostSpecific(DartType t, DartType s) {
|
| if (isMoreSpecific(t, s)) {
|
| return t;
|
| @@ -1644,13 +1634,14 @@ class Types implements DartTypes {
|
| DartType computeLeastUpperBound(DartType a, DartType b) {
|
| if (a == b) return a;
|
|
|
| - if (a.isTypeVariable ||
|
| - b.isTypeVariable) {
|
| + if (a.isTypeVariable || b.isTypeVariable) {
|
| return computeLeastUpperBoundTypeVariableTypes(a, b);
|
| }
|
|
|
| - a = a.unalias(resolution);
|
| - b = b.unalias(resolution);
|
| + a.computeUnaliased(resolution);
|
| + a = a.unaliased;
|
| + b.computeUnaliased(resolution);
|
| + b = b.unaliased;
|
|
|
| if (a.treatAsDynamic || b.treatAsDynamic) return const DynamicType();
|
| if (a.isVoid || b.isVoid) return const VoidType();
|
| @@ -1699,19 +1690,22 @@ class Types implements DartTypes {
|
| /// unaliasedBound(U) = unaliasedBound(Baz) = ()->dynamic
|
| /// unaliasedBound(X) = unaliasedBound(Y) = `Object`
|
| ///
|
| - static DartType computeUnaliasedBound(Compiler compiler, DartType type) {
|
| + static DartType computeUnaliasedBound(
|
| + Resolution resolution,
|
| + DartType type) {
|
| DartType originalType = type;
|
| while (type.isTypeVariable) {
|
| TypeVariableType variable = type;
|
| type = variable.element.bound;
|
| if (type == originalType) {
|
| - type = compiler.objectClass.rawType;
|
| + type = resolution.coreTypes.objectType;
|
| }
|
| }
|
| if (type.isMalformed) {
|
| return const DynamicType();
|
| }
|
| - return type.unalias(compiler.resolution);
|
| + type.computeUnaliased(resolution);
|
| + return type.unaliased;
|
| }
|
|
|
| /// Computes the interface type of [type], which is the type that defines
|
| @@ -1741,13 +1735,15 @@ class Types implements DartTypes {
|
| /// When typechecking `o.foo` the interface type of the static type of `o` is
|
| /// used to lookup the existence and type of `foo`.
|
| ///
|
| - static InterfaceType computeInterfaceType(Compiler compiler, DartType type) {
|
| - type = computeUnaliasedBound(compiler, type);
|
| + static InterfaceType computeInterfaceType(
|
| + Resolution resolution,
|
| + DartType type) {
|
| + type = computeUnaliasedBound(resolution, type);
|
| if (type.treatAsDynamic) {
|
| return null;
|
| }
|
| if (type.isFunctionType) {
|
| - type = compiler.functionClass.rawType;
|
| + type = resolution.coreTypes.functionType;
|
| }
|
| assert(invariant(NO_LOCATION_SPANNABLE, type.isInterfaceType,
|
| message: "unexpected type kind ${type.kind}."));
|
| @@ -1761,7 +1757,7 @@ class Types implements DartTypes {
|
| * [:false:] only if we are sure no such substitution exists.
|
| */
|
| class PotentialSubtypeVisitor extends SubtypeVisitor {
|
| - PotentialSubtypeVisitor(Compiler compiler) : super(compiler);
|
| + PotentialSubtypeVisitor(Resolution resolution) : super(resolution);
|
|
|
| bool isSubtype(DartType t, DartType s) {
|
| if (t is TypeVariableType || s is TypeVariableType) {
|
| @@ -1779,10 +1775,10 @@ class PotentialSubtypeVisitor extends SubtypeVisitor {
|
| /// constraints are too complex or the two types are too different, `false`
|
| /// is returned. Otherwise, the [constraintMap] holds the valid constraints.
|
| class MoreSpecificSubtypeVisitor extends BaseDartTypeVisitor<bool, DartType> {
|
| - final Compiler compiler;
|
| + final Types types;
|
| Map<TypeVariableType, DartType> constraintMap;
|
|
|
| - MoreSpecificSubtypeVisitor(Compiler this.compiler);
|
| + MoreSpecificSubtypeVisitor(this.types);
|
|
|
| /// Compute an instance of [element] which is more specific than [supertype].
|
| /// If no instance is found, `null` is returned.
|
| @@ -1809,7 +1805,7 @@ class MoreSpecificSubtypeVisitor extends BaseDartTypeVisitor<bool, DartType> {
|
| }
|
|
|
| bool visitType(DartType type, DartType argument) {
|
| - return compiler.types.isMoreSpecific(type, argument);
|
| + return types.isMoreSpecific(type, argument);
|
| }
|
|
|
| bool visitTypes(List<DartType> a, List<DartType> b) {
|
| @@ -1822,7 +1818,7 @@ class MoreSpecificSubtypeVisitor extends BaseDartTypeVisitor<bool, DartType> {
|
|
|
| bool visitTypeVariableType(TypeVariableType type, DartType argument) {
|
| DartType constraint =
|
| - compiler.types.getMostSpecific(constraintMap[type], argument);
|
| + types.getMostSpecific(constraintMap[type], argument);
|
| constraintMap[type] = constraint;
|
| return constraint != null;
|
| }
|
|
|