Chromium Code Reviews| Index: pkg/kernel/lib/type_environment.dart |
| diff --git a/pkg/kernel/lib/type_environment.dart b/pkg/kernel/lib/type_environment.dart |
| index edefd06aee3a2058eb41122d63b5497ce07dbdec..4eb58a16db25617475e931a99962166842b5e102 100644 |
| --- a/pkg/kernel/lib/type_environment.dart |
| +++ b/pkg/kernel/lib/type_environment.dart |
| @@ -25,6 +25,9 @@ class TypeEnvironment extends SubtypeTester { |
| TypeEnvironment(this.coreTypes, this.hierarchy); |
| + @override |
| + bool get strongMode => false; |
| + |
| InterfaceType get objectType => coreTypes.objectClass.rawType; |
| InterfaceType get nullType => coreTypes.nullClass.rawType; |
| InterfaceType get boolType => coreTypes.boolClass.rawType; |
| @@ -38,6 +41,7 @@ class TypeEnvironment extends SubtypeTester { |
| Class get intClass => coreTypes.intClass; |
| Class get numClass => coreTypes.numClass; |
| + Class get futureOrClass => coreTypes.futureOrClass; |
| InterfaceType literalListType(DartType elementType) { |
| return new InterfaceType(coreTypes.listClass, <DartType>[elementType]); |
| @@ -142,6 +146,9 @@ abstract class SubtypeTester { |
| InterfaceType get objectType; |
| InterfaceType get rawFunctionType; |
| ClassHierarchy get hierarchy; |
| + Class get futureOrClass; |
| + InterfaceType futureType(DartType type); |
| + bool get strongMode; |
| /// Determines if the given type is at the bottom of the type hierarchy. May |
| /// be overridden in subclasses. |
| @@ -159,6 +166,37 @@ abstract class SubtypeTester { |
| if (identical(subtype, supertype)) return true; |
| if (isBottom(subtype)) return true; |
| if (isTop(supertype)) return true; |
| + |
| + // Handle FutureOr<T> union type. |
|
Paul Berry
2017/05/23 17:36:38
Note: the logic below comes from the analyzer impl
|
| + if (strongMode && |
| + subtype is InterfaceType && |
| + identical(subtype.classNode, futureOrClass)) { |
| + var subtypeArg = subtype.typeArguments[0]; |
| + if (supertype is InterfaceType && |
| + identical(supertype.classNode, futureOrClass)) { |
| + var supertypeArg = supertype.typeArguments[0]; |
| + // FutureOr<A> <: FutureOr<B> iff A <: B |
| + return isSubtypeOf(subtypeArg, supertypeArg); |
| + } |
| + |
| + // given t1 is Future<A> | A, then: |
| + // (Future<A> | A) <: t2 iff Future<A> <: t2 and A <: t2. |
| + var subtypeFuture = futureType(subtypeArg); |
| + return isSubtypeOf(subtypeFuture, supertype) && |
| + isSubtypeOf(subtypeArg, supertype); |
| + } |
| + |
| + if (strongMode && |
| + supertype is InterfaceType && |
| + identical(supertype.classNode, futureOrClass)) { |
| + // given t2 is Future<A> | A, then: |
| + // t1 <: (Future<A> | A) iff t1 <: Future<A> or t1 <: A |
| + var supertypeArg = supertype.typeArguments[0]; |
| + var supertypeFuture = futureType(supertypeArg); |
| + return isSubtypeOf(subtype, supertypeFuture) || |
| + isSubtypeOf(subtype, supertypeArg); |
| + } |
| + |
| if (subtype is InterfaceType && supertype is InterfaceType) { |
| var upcastType = |
| hierarchy.getTypeAsInstanceOf(subtype, supertype.classNode); |