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

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

Issue 1462133005: Downwards inference. This adds support to the resolver for downwards (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Address comments 2 Created 5 years 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
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 2a051be9b83e2b9b79f7a9e17b2dcd8b60abc540..187890de70c67a0b548776f7edd228442b3744e4 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -960,9 +960,9 @@ void main() {
testChecker('downwards inference: miscellaneous', {
'/main.dart': '''
- typedef (T x);
+ typedef T Function2<S, T>(S x);
class A<T> {
- Function2<T> x;
+ Function2<T, T> x;
A(this.x);
}
void main() {
@@ -970,7 +970,7 @@ void main() {
var x = "hello";
var y = 3;
void f(List<Map<int, String>> l) {};
- f(/*info:InferredTypeLiteral*/[{y: x}]);
+ f(/*info:InferredTypeLiteral*/[/*info:InferredTypeLiteral*/{y: x}]);
}
{
int f(int x) {};
@@ -1024,8 +1024,8 @@ void main() {
A<int, String> a5 = /*severe:StaticTypeError*/new A<dynamic, dynamic>.named(3, "hello");
}
{
- A<int, String> a0 = /*severe:StaticTypeError*/new A("hello", 3);
- A<int, String> a1 = /*severe:StaticTypeError*/new A.named("hello", 3);
+ A<int, String> a0 = /*info:InferredTypeAllocation*/new A(/*severe:StaticTypeError*/"hello", /*severe:StaticTypeError*/3);
+ A<int, String> a1 = /*info:InferredTypeAllocation*/new A.named(/*severe:StaticTypeError*/"hello", /*severe:StaticTypeError*/3);
}
{
A<int, String> a0 = /*$info*/new B("hello", 3);
@@ -1036,8 +1036,8 @@ void main() {
A<int, String> a5 = /*severe:StaticTypeError*/new B<dynamic, dynamic>.named("hello", 3);
}
{
- A<int, String> a0 = /*severe:StaticTypeError*/new B(3, "hello");
- A<int, String> a1 = /*severe:StaticTypeError*/new B.named(3, "hello");
+ A<int, String> a0 = /*info:InferredTypeAllocation*/new B(/*severe:StaticTypeError*/3, /*severe:StaticTypeError*/"hello");
+ A<int, String> a1 = /*info:InferredTypeAllocation*/new B.named(/*severe:StaticTypeError*/3, /*severe:StaticTypeError*/"hello");
}
{
A<int, int> a0 = /*$info*/new C(3);
@@ -1048,8 +1048,8 @@ void main() {
A<int, int> a5 = /*severe:StaticTypeError*/new C<dynamic>.named(3);
}
{
- A<int, int> a0 = /*severe:StaticTypeError*/new C("hello");
- A<int, int> a1 = /*severe:StaticTypeError*/new C.named("hello");
+ A<int, int> a0 = /*info:InferredTypeAllocation*/new C(/*severe:StaticTypeError*/"hello");
+ A<int, int> a1 = /*info:InferredTypeAllocation*/new C.named(/*severe:StaticTypeError*/"hello");
}
{
A<int, String> a0 = /*$info*/new D("hello");
@@ -1060,19 +1060,19 @@ void main() {
A<int, String> a5 = /*severe:StaticTypeError*/new D<dynamic, dynamic>.named("hello");
}
{
- A<int, String> a0 = /*severe:StaticTypeError*/new D(3);
- A<int, String> a1 = /*severe:StaticTypeError*/new D.named(3);
+ A<int, String> a0 = /*info:InferredTypeAllocation*/new D(/*severe:StaticTypeError*/3);
+ A<int, String> a1 = /*info:InferredTypeAllocation*/new D.named(/*severe:StaticTypeError*/3);
}
{ // Currently we only allow variable constraints. Test that we reject.
A<C<int>, String> a0 = /*severe:StaticTypeError*/new E("hello");
}
{ // Check named and optional arguments
- A<int, String> a0 = /*$info*/new F(3, "hello", a: [3], b: ["hello"]);
- A<int, String> a1 = /*severe:StaticTypeError*/new F(3, "hello", a: ["hello"], b:[3]);
+ A<int, String> a0 = /*$info*/new F(3, "hello", a: /*info:InferredTypeLiteral*/[3], b: /*info:InferredTypeLiteral*/["hello"]);
+ A<int, String> a1 = /*info:InferredTypeAllocation*/new F(3, "hello", a: /*info:InferredTypeLiteral*/[/*severe:StaticTypeError*/"hello"], b: /*info:InferredTypeLiteral*/[/*severe:StaticTypeError*/3]);
A<int, String> a2 = /*$info*/new F.named(3, "hello", 3, "hello");
A<int, String> a3 = /*$info*/new F.named(3, "hello");
- A<int, String> a4 = /*severe:StaticTypeError*/new F.named(3, "hello", "hello", 3);
- A<int, String> a5 = /*severe:StaticTypeError*/new F.named(3, "hello", "hello");
+ A<int, String> a4 = /*info:InferredTypeAllocation*/new F.named(3, "hello", /*severe:StaticTypeError*/"hello", /*severe:StaticTypeError*/3);
+ A<int, String> a5 = /*info:InferredTypeAllocation*/new F.named(3, "hello", /*severe:StaticTypeError*/"hello");
}
}
''';
@@ -1083,15 +1083,15 @@ void main() {
String info = "info:InferredTypeLiteral";
String code = '''
void foo([List<String> list1 = /*$info*/const [],
- List<String> list2 = /*severe:StaticTypeError*/const [42]]) {
+ List<String> list2 = /*info:InferredTypeLiteral*/const [/*severe:StaticTypeError*/42]]) {
}
void main() {
{
List<int> l0 = /*$info*/[];
List<int> l1 = /*$info*/[3];
- List<int> l2 = /*severe:StaticTypeError*/["hello"];
- List<int> l3 = /*severe:StaticTypeError*/["hello", 3];
+ List<int> l2 = /*info:InferredTypeLiteral*/[/*severe:StaticTypeError*/"hello"];
+ List<int> l3 = /*info:InferredTypeLiteral*/[/*severe:StaticTypeError*/"hello", 3];
}
{
List<dynamic> l0 = [];
@@ -1108,14 +1108,14 @@ void main() {
{
Iterable<int> i0 = /*$info*/[];
Iterable<int> i1 = /*$info*/[3];
- Iterable<int> i2 = /*severe:StaticTypeError*/["hello"];
- Iterable<int> i3 = /*severe:StaticTypeError*/["hello", 3];
+ Iterable<int> i2 = /*info:InferredTypeLiteral*/[/*severe:StaticTypeError*/"hello"];
+ Iterable<int> i3 = /*info:InferredTypeLiteral*/[/*severe:StaticTypeError*/"hello", 3];
}
{
const List<int> c0 = /*$info*/const [];
const List<int> c1 = /*$info*/const [3];
- const List<int> c2 = /*severe:StaticTypeError*/const ["hello"];
- const List<int> c3 = /*severe:StaticTypeError*/const ["hello", 3];
+ const List<int> c2 = /*info:InferredTypeLiteral*/const [/*severe:StaticTypeError*/"hello"];
+ const List<int> c3 = /*info:InferredTypeLiteral*/const [/*severe:StaticTypeError*/"hello", 3];
}
}
''';
@@ -1133,28 +1133,28 @@ void main() {
void main() {
f0(/*$info*/[]);
f0(/*$info*/[3]);
- f0(/*severe:StaticTypeError*/["hello"]);
- f0(/*severe:StaticTypeError*/["hello", 3]);
+ f0(/*info:InferredTypeLiteral*/[/*severe:StaticTypeError*/"hello"]);
+ f0(/*info:InferredTypeLiteral*/[/*severe:StaticTypeError*/"hello", 3]);
f1(a: /*$info*/[]);
f1(a: /*$info*/[3]);
- f1(a: /*severe:StaticTypeError*/["hello"]);
- f1(a: /*severe:StaticTypeError*/["hello", 3]);
+ f1(a: /*$info*/[/*severe:StaticTypeError*/"hello"]);
+ f1(a: /*$info*/[/*severe:StaticTypeError*/"hello", 3]);
f2(/*$info*/[]);
f2(/*$info*/[3]);
- f2(/*severe:StaticTypeError*/["hello"]);
- f2(/*severe:StaticTypeError*/["hello", 3]);
+ f2(/*$info*/[/*severe:StaticTypeError*/"hello"]);
+ f2(/*$info*/[/*severe:StaticTypeError*/"hello", 3]);
f3(/*$info*/[]);
- f3(/*$info*/[[3]]);
- f3(/*severe:StaticTypeError*/[["hello"]]);
- f3(/*severe:StaticTypeError*/[["hello"], [3]]);
+ f3(/*$info*/[/*$info*/[3]]);
+ f3(/*$info*/[/*$info*/[/*severe:StaticTypeError*/"hello"]]);
+ f3(/*$info*/[/*$info*/[/*severe:StaticTypeError*/"hello"], /*$info*/[3]]);
f4(a: /*$info*/[]);
- f4(a: /*$info*/[[3]]);
- f4(a: /*severe:StaticTypeError*/[["hello"]]);
- f4(a: /*severe:StaticTypeError*/[["hello"], [3]]);
+ f4(a: /*$info*/[/*$info*/[3]]);
+ f4(a: /*$info*/[/*$info*/[/*severe:StaticTypeError*/"hello"]]);
+ f4(a: /*$info*/[/*$info*/[/*severe:StaticTypeError*/"hello"], /*$info*/[3]]);
}
''';
testChecker('infer downwards', {'/main.dart': code});
@@ -1164,15 +1164,15 @@ void main() {
String info = "info:InferredTypeLiteral";
String code = '''
void foo([Map<int, String> m1 = /*$info*/const {1: "hello"},
- Map<int, String> m1 = /*severe:StaticTypeError*/const {"hello": "world"}]) {
+ Map<int, String> m1 = /*$info*/const {(/*severe:StaticTypeError*/"hello"): "world"}]) {
}
void main() {
{
Map<int, String> l0 = /*$info*/{};
Map<int, String> l1 = /*$info*/{3: "hello"};
- Map<int, String> l2 = /*severe:StaticTypeError*/{"hello": "hello"};
- Map<int, String> l3 = /*severe:StaticTypeError*/{3: 3};
- Map<int, String> l4 = /*severe:StaticTypeError*/{3:"hello", "hello": 3};
+ Map<int, String> l2 = /*$info*/{(/*severe:StaticTypeError*/"hello"): "hello"};
+ Map<int, String> l3 = /*$info*/{3: /*severe:StaticTypeError*/3};
+ Map<int, String> l4 = /*$info*/{3:"hello", (/*severe:StaticTypeError*/"hello"): /*severe:StaticTypeError*/3};
}
{
Map<dynamic, dynamic> l0 = {};
@@ -1185,15 +1185,15 @@ void main() {
Map<dynamic, String> l0 = /*$info*/{};
Map<dynamic, String> l1 = /*$info*/{3: "hello"};
Map<dynamic, String> l2 = /*$info*/{"hello": "hello"};
- Map<dynamic, String> l3 = /*severe:StaticTypeError*/{3: 3};
- Map<dynamic, String> l4 = /*severe:StaticTypeError*/{3:"hello", "hello": 3};
+ Map<dynamic, String> l3 = /*$info*/{3: /*severe:StaticTypeError*/3};
+ Map<dynamic, String> l4 = /*$info*/{3:"hello", "hello": /*severe:StaticTypeError*/3};
}
{
Map<int, dynamic> l0 = /*$info*/{};
Map<int, dynamic> l1 = /*$info*/{3: "hello"};
- Map<int, dynamic> l2 = /*severe:StaticTypeError*/{"hello": "hello"};
+ Map<int, dynamic> l2 = /*$info*/{(/*severe:StaticTypeError*/"hello"): "hello"};
Map<int, dynamic> l3 = /*$info*/{3: 3};
- Map<int, dynamic> l3 = /*severe:StaticTypeError*/{3:"hello", "hello": 3};
+ Map<int, dynamic> l4 = /*$info*/{3:"hello", (/*severe:StaticTypeError*/"hello"): 3};
}
{
Map<int, String> l0 = /*severe:StaticTypeError*/<num, dynamic>{};
@@ -1203,9 +1203,9 @@ void main() {
{
const Map<int, String> l0 = /*$info*/const {};
const Map<int, String> l1 = /*$info*/const {3: "hello"};
- const Map<int, String> l2 = /*severe:StaticTypeError*/const {"hello": "hello"};
- const Map<int, String> l3 = /*severe:StaticTypeError*/const {3: 3};
- const Map<int, String> l4 = /*severe:StaticTypeError*/const {3:"hello", "hello": 3};
+ const Map<int, String> l2 = /*$info*/const {(/*severe:StaticTypeError*/"hello"): "hello"};
+ const Map<int, String> l3 = /*$info*/const {3: /*severe:StaticTypeError*/3};
+ const Map<int, String> l4 = /*$info*/const {3:"hello", (/*severe:StaticTypeError*/"hello"): /*severe:StaticTypeError*/3};
}
}
''';
@@ -1218,36 +1218,114 @@ void main() {
void main () {
{
- Function2<int, String> l0 = (int x) => null;
+ Function2<int, String> l0 = /*info:InferredTypeClosure*/(int x) => null;
Function2<int, String> l1 = (int x) => "hello";
Function2<int, String> l2 = /*severe:StaticTypeError*/(String x) => "hello";
Function2<int, String> l3 = /*severe:StaticTypeError*/(int x) => 3;
- Function2<int, String> l4 = /*warning:UninferredClosure should be severe:StaticTypeError*/(int x) {return 3};
+ Function2<int, String> l4 = /*info:InferredTypeClosure*/(int x) {return /*severe:StaticTypeError*/3;};
}
{
- Function2<int, String> l0 = /*info:InferredTypeClosure*/(x) => null;
+ Function2<int, String> l0 = /*info:InferredTypeClosure, info:InferredTypeClosure*/(x) => null;
Function2<int, String> l1 = /*info:InferredTypeClosure*/(x) => "hello";
- Function2<int, String> l2 = /*severe:StaticTypeError*/(x) => 3;
- Function2<int, String> l3 = /*warning:UninferredClosure should be severe:StaticTypeError*/(x) {return 3};
+ Function2<int, String> l2 = /*info:InferredTypeClosure, severe:StaticTypeError*/(x) => 3;
+ Function2<int, String> l3 = /*info:InferredTypeClosure, info:InferredTypeClosure*/(x) {return /*severe:StaticTypeError*/3;};
+ Function2<int, String> l4 = /*info:InferredTypeClosure, info:InferredTypeClosure*/(x) {return /*severe:StaticTypeError*/x;};
}
{
- Function2<int, List<String>> l0 = (int x) => null;
- Function2<int, List<String>> l1 = /*info:InferredTypeClosure*/(int x) => ["hello"];
- Function2<int, List<String>> l2 = /*severe:StaticTypeError*/(String x) => ["hello"];
- Function2<int, List<String>> l3 = /*warning:UninferredClosure should be severe:StaticTypeError*/(int x) => [3];
- Function2<int, List<String>> l4 = /*warning:UninferredClosure should be severe:StaticTypeError*/(int x) {return [3]};
+ Function2<int, List<String>> l0 = /*info:InferredTypeClosure*/(int x) => null;
+ Function2<int, List<String>> l1 = (int x) => /*info:InferredTypeLiteral*/["hello"];
+ Function2<int, List<String>> l2 = /*severe:StaticTypeError*/(String x) => /*info:InferredTypeLiteral*/["hello"];
+ Function2<int, List<String>> l3 = (int x) => /*info:InferredTypeLiteral*/[/*severe:StaticTypeError*/3];
+ Function2<int, List<String>> l4 = /*info:InferredTypeClosure*/(int x) {return /*info:InferredTypeLiteral*/[/*severe:StaticTypeError*/3];};
}
{
Function2<int, int> l0 = /*info:InferredTypeClosure*/(x) => x;
- Function2<int, int> l1 = /*info:InferredTypeClosure*/(x) => /*info:DynamicInvoke should be pass*/x+1;
- Function2<int, String> l2 = /*info:InferredTypeClosure should be severe:StaticTypeError*/(x) => x;
- Function2<int, String> l3 = /*info:InferredTypeClosure should be severe:StaticTypeError*/(x) => /*info:DynamicInvoke should be pass*/x.substring(3);
- Function2<String, String> l4 = /*info:InferredTypeClosure*/(x) => /*info:DynamicInvoke should be pass*/x.substring(3);
+ Function2<int, int> l1 = /*info:InferredTypeClosure*/(x) => x+1;
+ Function2<int, String> l2 = /*info:InferredTypeClosure, severe:StaticTypeError*/(x) => x;
+ Function2<int, String> l3 = /*info:InferredTypeClosure, info:InferredTypeClosure*/(x) => /*info:DynamicCast, info:DynamicInvoke*/x.substring(3);
+ Function2<String, String> l4 = /*info:InferredTypeClosure*/(x) => x.substring(3);
}
}
'''
});
+ testChecker('downwards inference initializing formal, default formal', {
+ '/main.dart': '''
+ typedef T Function2<S, T>([S x]);
+ class Foo {
+ List<int> x;
+ Foo([this.x = /*info:InferredTypeLiteral*/const [1]]);
+ Foo.named([List<int> x = /*info:InferredTypeLiteral*/const [1]]);
+ }
+ void f([List<int> l = /*info:InferredTypeLiteral*/const [1]]) {}
+// We do this inference in an early task but don't preserve the infos.
+ Function2<List<int>, String> g = /*pass should be info:InferredTypeClosure*/([llll = /*info:InferredTypeLiteral*/const [1]]) => "hello";
+'''
+ });
+
+ testChecker('downwards inference async/await', {
+ '/main.dart': '''
+ import 'dart:async';
+ Future<int> test() async {
+ List<int> l0 = /*warning:DownCastComposite should be pass*/await /*pass should be info:InferredTypeLiteral*/[3];
+ List<int> l1 = await /*info:InferredTypeAllocation*/new Future.value(/*info:InferredTypeLiteral*/[3]);
+ '''
+ });
+
+ testChecker('downwards inference foreach', {
+ '/main.dart': '''
+ import 'dart:async';
+ void main() {
+ for(int x in /*info:InferredTypeLiteral*/[1, 2, 3]) {
+ }
+ await for(int x in /*info:InferredTypeAllocation*/new Stream()) {
+ }
+ }
+ '''
+ });
+
+ testChecker('downwards inference yield/yield*', {
+ '/main.dart': '''
+ import 'dart:async';
+ Stream<List<int>> foo() async* {
+ yield /*info:InferredTypeLiteral*/[];
+ yield /*severe:StaticTypeError*/new Stream();
+ yield* /*severe:StaticTypeError*/[];
+ yield* /*info:InferredTypeAllocation*/new Stream();
+ }
+
+ Iterable<Map<int, int>> bar() sync* {
+ yield /*info:InferredTypeLiteral*/{};
+ yield /*severe:StaticTypeError*/new List();
+ yield* /*severe:StaticTypeError*/{};
+ yield* /*info:InferredTypeAllocation*/new List();
+ }
+ '''
+ });
+
+ testChecker('downwards inference, annotations', {
+ '/main.dart': '''
+ class Foo {
+ const Foo(List<String> l);
+ const Foo.named(List<String> l);
+ }
+ @Foo(/*info:InferredTypeLiteral*/const [])
+ class Bar {}
+ @Foo.named(/*info:InferredTypeLiteral*/const [])
+ class Baz {}
+ '''
+ });
+
+ testChecker('downwards inference, assignment statements', {
+ '/main.dart': '''
+ void main() {
+ List<int> l;
+ l = /*info:InferredTypeLiteral*/[/*severe:StaticTypeError*/"hello"];
+ l = (l = /*info:InferredTypeLiteral*/[1]);
+ }
+'''
+ });
+
testChecker('inferred initializing formal checks default value', {
'/main.dart': '''
class Foo {

Powered by Google App Engine
This is Rietveld 408576698