| Index: sdk/lib/_internal/compiler/implementation/types/types.dart
|
| diff --git a/sdk/lib/_internal/compiler/implementation/types/types.dart b/sdk/lib/_internal/compiler/implementation/types/types.dart
|
| index d4a83b987003c08ef1da3a144332cd5e777ea4cd..7e2983d01f235be572cacb93ae1be726faeb7103 100644
|
| --- a/sdk/lib/_internal/compiler/implementation/types/types.dart
|
| +++ b/sdk/lib/_internal/compiler/implementation/types/types.dart
|
| @@ -68,7 +68,7 @@ class TypesTask extends CompilerTask {
|
|
|
| TypeMask get dynamicType {
|
| if (dynamicTypeCache == null) {
|
| - dynamicTypeCache = new TypeMask.subclass(compiler.objectClass.rawType);
|
| + dynamicTypeCache = new TypeMask.subclass(compiler.objectClass);
|
| }
|
| return dynamicTypeCache;
|
| }
|
| @@ -76,7 +76,7 @@ class TypesTask extends CompilerTask {
|
| TypeMask get intType {
|
| if (intTypeCache == null) {
|
| intTypeCache = new TypeMask.nonNullExact(
|
| - compiler.backend.intImplementation.rawType);
|
| + compiler.backend.intImplementation);
|
| }
|
| return intTypeCache;
|
| }
|
| @@ -84,7 +84,7 @@ class TypesTask extends CompilerTask {
|
| TypeMask get doubleType {
|
| if (doubleTypeCache == null) {
|
| doubleTypeCache = new TypeMask.nonNullExact(
|
| - compiler.backend.doubleImplementation.rawType);
|
| + compiler.backend.doubleImplementation);
|
| }
|
| return doubleTypeCache;
|
| }
|
| @@ -92,7 +92,7 @@ class TypesTask extends CompilerTask {
|
| TypeMask get numType {
|
| if (numTypeCache == null) {
|
| numTypeCache = new TypeMask.nonNullSubclass(
|
| - compiler.backend.numImplementation.rawType);
|
| + compiler.backend.numImplementation);
|
| }
|
| return numTypeCache;
|
| }
|
| @@ -100,7 +100,7 @@ class TypesTask extends CompilerTask {
|
| TypeMask get boolType {
|
| if (boolTypeCache == null) {
|
| boolTypeCache = new TypeMask.nonNullExact(
|
| - compiler.backend.boolImplementation.rawType);
|
| + compiler.backend.boolImplementation);
|
| }
|
| return boolTypeCache;
|
| }
|
| @@ -108,7 +108,7 @@ class TypesTask extends CompilerTask {
|
| TypeMask get functionType {
|
| if (functionTypeCache == null) {
|
| functionTypeCache = new TypeMask.nonNullSubtype(
|
| - compiler.backend.functionImplementation.rawType);
|
| + compiler.backend.functionImplementation);
|
| }
|
| return functionTypeCache;
|
| }
|
| @@ -116,7 +116,7 @@ class TypesTask extends CompilerTask {
|
| TypeMask get listType {
|
| if (listTypeCache == null) {
|
| listTypeCache = new TypeMask.nonNullExact(
|
| - compiler.backend.listImplementation.rawType);
|
| + compiler.backend.listImplementation);
|
| }
|
| return listTypeCache;
|
| }
|
| @@ -124,7 +124,7 @@ class TypesTask extends CompilerTask {
|
| TypeMask get constListType {
|
| if (constListTypeCache == null) {
|
| constListTypeCache = new TypeMask.nonNullExact(
|
| - compiler.backend.constListImplementation.rawType);
|
| + compiler.backend.constListImplementation);
|
| }
|
| return constListTypeCache;
|
| }
|
| @@ -132,7 +132,7 @@ class TypesTask extends CompilerTask {
|
| TypeMask get fixedListType {
|
| if (fixedListTypeCache == null) {
|
| fixedListTypeCache = new TypeMask.nonNullExact(
|
| - compiler.backend.fixedListImplementation.rawType);
|
| + compiler.backend.fixedListImplementation);
|
| }
|
| return fixedListTypeCache;
|
| }
|
| @@ -140,7 +140,7 @@ class TypesTask extends CompilerTask {
|
| TypeMask get growableListType {
|
| if (growableListTypeCache == null) {
|
| growableListTypeCache = new TypeMask.nonNullExact(
|
| - compiler.backend.growableListImplementation.rawType);
|
| + compiler.backend.growableListImplementation);
|
| }
|
| return growableListTypeCache;
|
| }
|
| @@ -148,7 +148,7 @@ class TypesTask extends CompilerTask {
|
| TypeMask get mapType {
|
| if (mapTypeCache == null) {
|
| mapTypeCache = new TypeMask.nonNullSubtype(
|
| - compiler.backend.mapImplementation.rawType);
|
| + compiler.backend.mapImplementation);
|
| }
|
| return mapTypeCache;
|
| }
|
| @@ -156,7 +156,7 @@ class TypesTask extends CompilerTask {
|
| TypeMask get constMapType {
|
| if (constMapTypeCache == null) {
|
| constMapTypeCache = new TypeMask.nonNullSubtype(
|
| - compiler.backend.constMapImplementation.rawType);
|
| + compiler.backend.constMapImplementation);
|
| }
|
| return constMapTypeCache;
|
| }
|
| @@ -164,7 +164,7 @@ class TypesTask extends CompilerTask {
|
| TypeMask get stringType {
|
| if (stringTypeCache == null) {
|
| stringTypeCache = new TypeMask.nonNullExact(
|
| - compiler.backend.stringImplementation.rawType);
|
| + compiler.backend.stringImplementation);
|
| }
|
| return stringTypeCache;
|
| }
|
| @@ -172,7 +172,7 @@ class TypesTask extends CompilerTask {
|
| TypeMask get typeType {
|
| if (typeTypeCache == null) {
|
| typeTypeCache = new TypeMask.nonNullExact(
|
| - compiler.backend.typeImplementation.rawType);
|
| + compiler.backend.typeImplementation);
|
| }
|
| return typeTypeCache;
|
| }
|
| @@ -209,18 +209,17 @@ class TypesTask extends CompilerTask {
|
| return cls;
|
| }
|
|
|
| - /// Checks that two [DartType]s are the same modulo normalization.
|
| - bool same(DartType type1, DartType type2) {
|
| - return (type1 == type2)
|
| - || normalize(type1.element) == normalize(type2.element);
|
| + /// Checks that two types are the same modulo normalization.
|
| + bool same(ClassElement type1, ClassElement type2) {
|
| + return (type1 == type2) || normalize(type1) == normalize(type2);
|
| }
|
|
|
| /**
|
| * Checks that one of [type1] and [type2] is a subtype of the other.
|
| */
|
| - bool related(DartType type1, DartType type2) {
|
| - return compiler.types.isSubtype(type1, type2)
|
| - || compiler.types.isSubtype(type2, type1);
|
| + bool related(ClassElement type1, ClassElement type2) {
|
| + return compiler.types.isSubtype(type1.rawType, type2.rawType)
|
| + || compiler.types.isSubtype(type2.rawType, type1.rawType);
|
| }
|
|
|
| /**
|
| @@ -228,18 +227,20 @@ class TypesTask extends CompilerTask {
|
| * exactness, subclassing, subtyping and nullability. The [element] parameter
|
| * is for debugging purposes only and can be omitted.
|
| */
|
| - TypeMask best(var type1, var type2, [element]) {
|
| + FlatTypeMask best(TypeMask type1, TypeMask type2, [element]) {
|
| // TODO(polux): Handle [UnionTypeMask].
|
| if (type1 != null) type1 = type1.simplify(compiler);
|
| if (type2 != null) type2 = type2.simplify(compiler);
|
| - final result = _best(type1, type2);
|
| + FlatTypeMask result = _best(type1, type2);
|
| // Tests type1 and type2 for equality modulo normalization of native types.
|
| // Only called when DUMP_SURPRISING_RESULTS is true.
|
| bool similar() {
|
| if (type1 == null || type2 == null || type1.isEmpty || type2.isEmpty) {
|
| return type1 == type2;
|
| }
|
| - return same(type1.base, type2.base);
|
| + FlatTypeMask flat1 = type1;
|
| + FlatTypeMask flat2 = type2;
|
| + return same(flat1.base, flat2.base);
|
| }
|
| if (DUMP_SURPRISING_RESULTS && result == type1 && !similar()) {
|
| print("$type1 better than $type2 for $element");
|
| @@ -248,54 +249,56 @@ class TypesTask extends CompilerTask {
|
| }
|
|
|
| /// Helper method for [best].
|
| - TypeMask _best(var type1, var type2) {
|
| + FlatTypeMask _best(var type1, var type2) {
|
| if (type1 == null) return type2;
|
| if (type2 == null) return type1;
|
| - if (type1.isContainer) type1 = type1.asFlat;
|
| - if (type2.isContainer) type2 = type2.asFlat;
|
| - if (type1.isExact) {
|
| - if (type2.isExact) {
|
| + FlatTypeMask flat1 = type1.isContainer ? type1.asFlat : type1;
|
| + FlatTypeMask flat2 = type2.isContainer ? type2.asFlat : type2;
|
| + if (flat1.isExact) {
|
| + if (flat2.isExact) {
|
| // TODO(polux): Update the code to not have this situation.
|
| - if (type1.base != type2.base) return type1;
|
| - assert(same(type1.base, type2.base));
|
| - return type1.isNullable ? type2 : type1;
|
| + if (flat1.base != flat2.base) return flat1;
|
| + assert(same(flat1.base, flat2.base));
|
| + return flat1.isNullable ? flat2 : flat1;
|
| } else {
|
| - return type1;
|
| + return flat1;
|
| }
|
| - } else if (type2.isExact) {
|
| - return type2;
|
| - } else if (type1.isSubclass) {
|
| - if (type2.isSubclass) {
|
| - assert(related(type1.base, type2.base));
|
| - if (same(type1.base, type2.base)) {
|
| - return type1.isNullable ? type2 : type1;
|
| - } else if (compiler.types.isSubtype(type1.base, type2.base)) {
|
| - return type1;
|
| + } else if (flat2.isExact) {
|
| + return flat2;
|
| + } else if (flat1.isSubclass) {
|
| + if (flat2.isSubclass) {
|
| + assert(related(flat1.base, flat2.base));
|
| + if (same(flat1.base, flat2.base)) {
|
| + return flat1.isNullable ? flat2 : flat1;
|
| + } else if (compiler.types.isSubtype(flat1.base.rawType,
|
| + flat2.base.rawType)) {
|
| + return flat1;
|
| } else {
|
| - return type2;
|
| + return flat2;
|
| }
|
| } else {
|
| - return type1;
|
| + return flat1;
|
| }
|
| - } else if (type2.isSubclass) {
|
| - return type2;
|
| - } else if (type1.isSubtype) {
|
| - if (type2.isSubtype) {
|
| - assert(related(type1.base, type2.base));
|
| - if (same(type1.base, type2.base)) {
|
| - return type1.isNullable ? type2 : type1;
|
| - } else if (compiler.types.isSubtype(type1.base, type2.base)) {
|
| - return type1;
|
| + } else if (flat2.isSubclass) {
|
| + return flat2;
|
| + } else if (flat1.isSubtype) {
|
| + if (flat2.isSubtype) {
|
| + assert(related(flat1.base, flat2.base));
|
| + if (same(flat1.base, flat2.base)) {
|
| + return flat1.isNullable ? flat2 : flat1;
|
| + } else if (compiler.types.isSubtype(flat1.base.rawType,
|
| + flat2.base.rawType)) {
|
| + return flat1;
|
| } else {
|
| - return type2;
|
| + return flat2;
|
| }
|
| } else {
|
| - return type1;
|
| + return flat1;
|
| }
|
| - } else if (type2.isSubtype) {
|
| - return type2;
|
| + } else if (flat2.isSubtype) {
|
| + return flat2;
|
| } else {
|
| - return type1.isNullable ? type2 : type1;
|
| + return flat1.isNullable ? flat2 : flat1;
|
| }
|
| }
|
|
|
|
|