Skip to content

Commit 694c8d0

Browse files
scheglovcommit-bot@chromium.org
authored andcommitted
Update UP for FutureOr.
Bug: dart-lang/sdk#43720 Change-Id: I9decd3a3b430f82e3e4bd0c4e6963cd3069f9adf Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/166786 Reviewed-by: Samuel Rawlins <srawlins@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
1 parent 63e0cd6 commit 694c8d0

File tree

2 files changed

+99
-0
lines changed

2 files changed

+99
-0
lines changed

pkg/analyzer/lib/src/dart/element/least_upper_bound.dart

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,11 @@ class LeastUpperBoundHelper {
677677
return getLeastUpperBound(T1, _typeSystem.objectNone);
678678
}
679679

680+
var futureOrResult = _futureOr(T1, T2);
681+
if (futureOrResult != null) {
682+
return futureOrResult;
683+
}
684+
680685
// UP(T1, T2) = T2 if T1 <: T2
681686
// UP(T1, T2) = T1 if T2 <: T1
682687
// And other, more complex variants of interface types.
@@ -806,6 +811,56 @@ class LeastUpperBoundHelper {
806811
);
807812
}
808813

814+
DartType _futureOr(DartType T1, DartType T2) {
815+
var T1_futureOr = T1 is InterfaceType && T1.isDartAsyncFutureOr
816+
? T1.typeArguments[0]
817+
: null;
818+
819+
var T1_future = T1 is InterfaceType && T1.isDartAsyncFuture
820+
? T1.typeArguments[0]
821+
: null;
822+
823+
var T2_futureOr = T2 is InterfaceType && T2.isDartAsyncFutureOr
824+
? T2.typeArguments[0]
825+
: null;
826+
827+
var T2_future = T2 is InterfaceType && T2.isDartAsyncFuture
828+
? T2.typeArguments[0]
829+
: null;
830+
831+
// UP(FutureOr<T1>, FutureOr<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
832+
if (T1_futureOr != null && T2_futureOr != null) {
833+
var T3 = getLeastUpperBound(T1_futureOr, T2_futureOr);
834+
return _typeSystem.typeProvider.futureOrType2(T3);
835+
}
836+
837+
// UP(Future<T1>, FutureOr<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
838+
if (T1_future != null && T2_futureOr != null) {
839+
var T3 = getLeastUpperBound(T1_future, T2_futureOr);
840+
return _typeSystem.typeProvider.futureOrType2(T3);
841+
}
842+
843+
// UP(FutureOr<T1>, Future<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
844+
if (T1_futureOr != null && T2_future != null) {
845+
var T3 = getLeastUpperBound(T1_futureOr, T2_future);
846+
return _typeSystem.typeProvider.futureOrType2(T3);
847+
}
848+
849+
// UP(T1, FutureOr<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
850+
if (T2_futureOr != null) {
851+
var T3 = getLeastUpperBound(T1, T2_futureOr);
852+
return _typeSystem.typeProvider.futureOrType2(T3);
853+
}
854+
855+
// UP(FutureOr<T1>, T2) = FutureOr<T3> where T3 = UP(T1, T2)
856+
if (T1_futureOr != null) {
857+
var T3 = getLeastUpperBound(T1_futureOr, T2);
858+
return _typeSystem.typeProvider.futureOrType2(T3);
859+
}
860+
861+
return null;
862+
}
863+
809864
DartType _parameterType(ParameterElement a, ParameterElement b) {
810865
return _typeSystem.getGreatestLowerBound(a.type, b.type);
811866
}

pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2608,6 +2608,50 @@ class UpperBoundTest extends _BoundsTestBase {
26082608
);
26092609
}
26102610

2611+
/// UP(Future<T1>, FutureOr<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
2612+
/// UP(FutureOr<T1>, Future<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
2613+
test_futureOr_future() {
2614+
void check(DartType T1, DartType T2, DartType expected) {
2615+
_checkLeastUpperBound(
2616+
futureNone(T1),
2617+
futureOrNone(T2),
2618+
futureOrNone(expected),
2619+
);
2620+
}
2621+
2622+
check(intNone, doubleNone, numNone);
2623+
check(intNone, stringNone, objectNone);
2624+
}
2625+
2626+
/// UP(FutureOr<T1>, FutureOr<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
2627+
test_futureOr_futureOr() {
2628+
void check(DartType T1, DartType T2, DartType expected) {
2629+
_checkLeastUpperBound(
2630+
futureOrNone(T1),
2631+
futureOrNone(T2),
2632+
futureOrNone(expected),
2633+
);
2634+
}
2635+
2636+
check(intNone, doubleNone, numNone);
2637+
check(intNone, stringNone, objectNone);
2638+
}
2639+
2640+
/// UP(T1, FutureOr<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
2641+
/// UP(FutureOr<T1>, T2) = FutureOr<T3> where T3 = UP(T1, T2)
2642+
test_futureOr_other() {
2643+
void check(DartType T1, DartType T2, DartType expected) {
2644+
_checkLeastUpperBound(
2645+
futureOrNone(T1),
2646+
T2,
2647+
futureOrNone(expected),
2648+
);
2649+
}
2650+
2651+
check(intNone, doubleNone, numNone);
2652+
check(intNone, stringNone, objectNone);
2653+
}
2654+
26112655
test_identical() {
26122656
void check(DartType type) {
26132657
_checkLeastUpperBound(type, type, type);

0 commit comments

Comments
 (0)