Better FutureOr support, failing test.
Change-Id: Ib662286a58fb9389ce1065d87835613f3b899be4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/106968
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Mike Fairhurst <mfairhurst@google.com>
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 9a902c2..879f4e7 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -65,11 +65,17 @@
}
/// Is [t] the top of the legacy type hierarch.
-bool _isLegacyTop(DartType t, {@required bool orTrueTop}) =>
-// TODO(mfairhurst): handle FutureOr<LegacyTop> cases, with tests.
- (t.isObject &&
- (t as TypeImpl).nullabilitySuffix == NullabilitySuffix.none) ||
- (orTrueTop ? _isTop(t) : false);
+bool _isLegacyTop(DartType t, {@required bool orTrueTop}) {
+ if (t.isDartAsyncFutureOr) {
+ return _isLegacyTop((t as InterfaceType).typeArguments[0],
+ orTrueTop: orTrueTop);
+ }
+ if (t.isObject &&
+ (t as TypeImpl).nullabilitySuffix == NullabilitySuffix.none) {
+ return true;
+ }
+ return orTrueTop ? _isTop(t) : false;
+}
bool _isTop(DartType t) {
if (t.isDartAsyncFutureOr) {
@@ -631,6 +637,7 @@
}
// Legacy top case. Must be done now to find Object* <: Object.
+ // TODO: handle false positives like FutureOr<Object?>* and T* extends int?.
if (t1.nullabilitySuffix == NullabilitySuffix.star &&
_isLegacyTop(t2, orTrueTop: false)) {
return true;
diff --git a/pkg/analyzer/test/generated/type_system_test.dart b/pkg/analyzer/test/generated/type_system_test.dart
index d4792a5..abbf98e 100644
--- a/pkg/analyzer/test/generated/type_system_test.dart
+++ b/pkg/analyzer/test/generated/type_system_test.dart
@@ -2108,6 +2108,46 @@
_checkGroups(dynamicType, equivalents: equivalents, subtypes: subtypes);
}
+ @failingTest
+ void test_futureOr_topTypes() {
+ var objectStar =
+ (objectType as TypeImpl).withNullability(NullabilitySuffix.star);
+ var objectQuestion =
+ (objectType as TypeImpl).withNullability(NullabilitySuffix.question);
+ var futureOrObject = futureOrType.instantiate([objectType]);
+ var futureOrObjectStar = futureOrType.instantiate([objectStar]);
+ var futureOrObjectQuestion = futureOrType.instantiate([objectQuestion]);
+ var futureOrStarObject =
+ (futureOrObject as TypeImpl).withNullability(NullabilitySuffix.star);
+ var futureOrQuestionObject = (futureOrObject as TypeImpl)
+ .withNullability(NullabilitySuffix.question);
+ var futureOrStarObjectStar = (futureOrObjectStar as TypeImpl)
+ .withNullability(NullabilitySuffix.star);
+ var futureOrQuestionObjectStar = (futureOrObjectStar as TypeImpl)
+ .withNullability(NullabilitySuffix.question);
+ var futureOrStarObjectQuestion = (futureOrObjectQuestion as TypeImpl)
+ .withNullability(NullabilitySuffix.star);
+ var futureOrQuestionObjectQuestion = (futureOrObjectQuestion as TypeImpl)
+ .withNullability(NullabilitySuffix.question);
+
+ //FutureOr<Object> <: FutureOr*<Object?>
+ _checkGroups(futureOrObject, equivalents: [
+ objectStar,
+ futureOrObjectStar,
+ futureOrStarObject,
+ futureOrStarObjectStar,
+ objectType
+ ], subtypes: [], supertypes: [
+ objectQuestion,
+ futureOrQuestionObject,
+ futureOrObjectQuestion,
+ futureOrQuestionObject,
+ futureOrQuestionObjectStar,
+ futureOrStarObjectQuestion,
+ futureOrQuestionObjectQuestion
+ ]);
+ }
+
void test_int_nullableTypes() {
List<DartType> equivalents = <DartType>[
intType,