Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(695)

Unified Diff: pkg/analyzer/test/src/task/strong/inferred_type_test.dart

Issue 2676633005: Temporarily restore ad hoc Future.then inference (Closed)
Patch Set: Address comments Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/analyzer/lib/src/generated/static_type_analyzer.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/test/src/task/strong/inferred_type_test.dart
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index 6077b7c07a911edea7849a07a965b6c4a461bc3b..66517db9911b74f96684a06d677182b23c064497 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -1695,14 +1695,16 @@ main() {
''');
}
- void test_futureThen() {
+ void test_futureThen_deprecated() {
+// Tests the deprecated ad hoc future inference for classes which implement
+// Future but haven't been updated to use FutureOr
String build({String declared, String downwards, String upwards}) => '''
import 'dart:async';
class MyFuture<T> implements Future<T> {
MyFuture() {}
MyFuture.value(T x) {}
dynamic noSuchMethod(invocation);
- MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+ MyFuture<S> then<S>(dynamic f(T x), {Function onError}) => null;
}
void main() {
@@ -1735,14 +1737,14 @@ void main() {
build(declared: "Future", downwards: "Future", upwards: "Future"));
}
- void test_futureThen_comment() {
+ void test_futureThen() {
String build({String declared, String downwards, String upwards}) => '''
import 'dart:async';
class MyFuture<T> implements Future<T> {
MyFuture() {}
MyFuture.value(T x) {}
dynamic noSuchMethod(invocation);
- MyFuture/*<S>*/ then/*<S>*/(dynamic f(T x), {Function onError}) => null;
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
}
void main() {
@@ -1775,6 +1777,40 @@ void main() {
build(declared: "Future", downwards: "Future", upwards: "Future"));
}
+ void test_futureThen_conditional_deprecated() {
+// Tests the deprecated ad hoc future inference for classes which implement
+// Future but haven't been updated to use FutureOr
+ String build({String declared, String downwards, String upwards}) => '''
+import 'dart:async';
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ dynamic noSuchMethod(invocation);
+ MyFuture<S> then<S>(dynamic f(T x), {Function onError}) => null;
+}
+
+void main() {
+ $declared<bool> f;
+ $downwards<int> t1 = f.then(/*info:INFERRED_TYPE_CLOSURE*/
+ (x) async => x ? 2 : await new $upwards<int>.value(3));
+ $downwards<int> t2 = f.then(/*info:INFERRED_TYPE_CLOSURE,info:INFERRED_TYPE_CLOSURE*/(x) async { // TODO(leafp): Why the duplicate here?
+ return await x ? 2 : new $upwards<int>.value(3);});
+ $downwards<int> t5 = f.then(/*info:INFERRED_TYPE_CLOSURE*/
+ (x) => x ? 2 : new $upwards<int>.value(3));
+ $downwards<int> t6 = f.then(/*info:INFERRED_TYPE_CLOSURE,info:INFERRED_TYPE_CLOSURE*/
+ (x) {return /*warning:DOWN_CAST_COMPOSITE*/x ? 2 : new $upwards<int>.value(3);});
+}
+''';
+ checkFile(
+ build(declared: "MyFuture", downwards: "Future", upwards: "Future"));
+ checkFile(
+ build(declared: "MyFuture", downwards: "Future", upwards: "MyFuture"));
+ checkFile(
+ build(declared: "MyFuture", downwards: "MyFuture", upwards: "Future"));
+ checkFile(build(
+ declared: "MyFuture", downwards: "MyFuture", upwards: "MyFuture"));
+ }
+
void test_futureThen_conditional() {
String build({String declared, String downwards, String upwards}) => '''
import 'dart:async';
@@ -1830,7 +1866,9 @@ main() {
import "dart:async";
m1() {
Future<int> f;
- var x = f.then<Future<List<int>>>(/*info:INFERRED_TYPE_CLOSURE,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/(x) => []);
+ var x = f.then<Future<List<int>>>(/*info:INFERRED_TYPE_CLOSURE,
+ error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/
+ (x) => /*info:INFERRED_TYPE_LITERAL*/[]);
Future<List<int>> y = x;
}
m2() {
@@ -1841,6 +1879,38 @@ m2() {
''');
}
+ void test_futureThen_upwards_deprecated() {
+ // Tests the deprecated ad hoc future inference for classes which implement
+ // Future but haven't been updated to use FutureOr
+ // Regression test for https://github.com/dart-lang/sdk/issues/27088.
+ String build({String declared, String downwards, String upwards}) => '''
+import 'dart:async';
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ dynamic noSuchMethod(invocation);
+ MyFuture<S> then<S>(dynamic f(T x), {Function onError}) => null;
+}
+
+void main() {
+ var f = foo().then((_) => 2.3);
+ $downwards<int> f2 = /*error:INVALID_ASSIGNMENT*/f;
+
+ // The unnecessary cast is to illustrate that we inferred <double> for
+ // the generic type args, even though we had a return type context.
+ $downwards<num> f3 = /*info:UNNECESSARY_CAST*/foo().then(
+ (_) => 2.3) as $upwards<double>;
+}
+$declared foo() => new $declared<int>.value(1);
+ ''';
+ checkFile(
+ build(declared: "MyFuture", downwards: "Future", upwards: "Future"));
+ checkFile(build(
+ declared: "MyFuture", downwards: "MyFuture", upwards: "MyFuture"));
+ checkFile(
+ build(declared: "Future", downwards: "Future", upwards: "Future"));
+ }
+
void test_futureThen_upwards() {
// Regression test for https://github.com/dart-lang/sdk/issues/27088.
String build({String declared, String downwards, String upwards}) => '''
@@ -1885,14 +1955,16 @@ main() {
''');
}
- void test_futureUnion_asyncConditional() {
+ void test_futureUnion_asyncConditional_deprecated() {
+ // Tests the deprecated ad hoc future inference for classes which implement
+ // Future but haven't been updated to use FutureOr
String build({String declared, String downwards, String upwards}) => '''
import 'dart:async';
class MyFuture<T> implements Future<T> {
MyFuture() {}
MyFuture.value(x) {}
dynamic noSuchMethod(invocation);
- MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+ MyFuture<S> then<S>(dynamic f(T x), {Function onError}) => null;
}
$downwards<int> g1(bool x) async {
@@ -1908,14 +1980,14 @@ $downwards<int> g3(bool x) async {
checkFile(build(downwards: "Future", upwards: "MyFuture"));
}
- void test_futureUnion_asyncConditional_comment() {
+ void test_futureUnion_asyncConditional() {
String build({String declared, String downwards, String upwards}) => '''
import 'dart:async';
class MyFuture<T> implements Future<T> {
MyFuture() {}
MyFuture.value(x) {}
dynamic noSuchMethod(invocation);
- MyFuture/*<S>*/ then/*<S>*/(dynamic f(T x), {Function onError}) => null;
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
}
$downwards<int> g1(bool x) async {
@@ -1931,6 +2003,48 @@ $downwards<int> g3(bool x) async {
checkFile(build(downwards: "Future", upwards: "MyFuture"));
}
+ void test_futureUnion_downwards_deprecated() {
+ // Tests the deprecated ad hoc future inference for classes which implement
+ // Future but haven't been updated to use FutureOr
+ String build({String declared, String downwards, String upwards}) {
+ // TODO(leafp): The use of matchTypes in visitInstanceCreationExpression
+ // in the resolver visitor isn't powerful enough to catch this for the
+ // subclass. See the TODO there.
+ var allocInfo =
+ (upwards == "Future") ? "/*info:INFERRED_TYPE_ALLOCATION*/" : "";
+ return '''
+import 'dart:async';
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value([x]) {}
+ dynamic noSuchMethod(invocation);
+ MyFuture<S> then<S>(dynamic f(T x), {Function onError}) => null;
+}
+
+$declared f;
+// Instantiates Future<int>
+$downwards<int> t1 = f.then((_) =>
+ ${allocInfo}new $upwards.value('hi'));
+
+// Instantiates List<int>
+$downwards<List<int>> t2 = f.then((_) => /*info:INFERRED_TYPE_LITERAL*/[3]);
+$downwards<List<int>> g2() async { return /*info:INFERRED_TYPE_LITERAL*/[3]; }
+$downwards<List<int>> g3() async {
+ return /*info:INFERRED_TYPE_ALLOCATION*/new $upwards.value(
+ /*info:INFERRED_TYPE_LITERAL*/[3]); }
+''';
+ }
+
+ checkFile(
+ build(declared: "MyFuture", downwards: "Future", upwards: "Future"));
+ checkFile(
+ build(declared: "MyFuture", downwards: "Future", upwards: "MyFuture"));
+ checkFile(
+ build(declared: "Future", downwards: "Future", upwards: "Future"));
+ checkFile(
+ build(declared: "Future", downwards: "Future", upwards: "MyFuture"));
+ }
+
void test_futureUnion_downwards() {
String build({String declared, String downwards, String upwards}) {
// TODO(leafp): The use of matchTypes in visitInstanceCreationExpression
« no previous file with comments | « pkg/analyzer/lib/src/generated/static_type_analyzer.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698