| 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 {
|
|
|