Chromium Code Reviews| Index: test/checker/inferred_type_test.dart |
| diff --git a/test/checker/inferred_type_test.dart b/test/checker/inferred_type_test.dart |
| index 12bcec6028d79c5ff19198a95a279fee9020fee4..de7f10d0b9f3f2c8cf5ba8417ad985b9cd18ad3d 100644 |
| --- a/test/checker/inferred_type_test.dart |
| +++ b/test/checker/inferred_type_test.dart |
| @@ -1179,4 +1179,189 @@ void main() { |
| ''' |
| }, inferFromOverrides: true, inferTransitively: true); |
| }); |
| + |
| + test('downwards inference on instance creations', () { |
| + String mk(String error) => ''' |
|
vsm
2015/03/27 21:20:59
minor nit: error->info since it's not an error in
|
| + class A<S, T> { |
| + S x; |
| + T y; |
| + A(this.x, this.y); |
| + A.named(this.x, this.y); |
| + } |
| + |
| + class B<S, T> extends A<T, S> { |
| + B(S y, T x) : super(x, y); |
| + B.named(S y, T x) : super.named(x, y); |
| + } |
| + |
| + class C<S> extends B<S, S> { |
| + C(S a) : super(a, a); |
| + C.named(S a) : super.named(a, a); |
| + } |
| + |
| + class D<S, T> extends B<T, int> { |
| + D(T a) : super(a, 3); |
| + D.named(T a) : super.named(a, 3); |
| + } |
| + |
| + class E<S, T> extends A<C<S>, T> { |
| + E(T a) : super(null, a); |
| + } |
| + |
| + void main() { |
| + { |
| + A<int, String> a0 = /*$error*/new A(3, "hello"); |
| + A<int, String> a1 = /*$error*/new A.named(3, "hello"); |
| + A<int, String> a2 = new A<int, String>(3, "hello"); |
| + A<int, String> a3 = new A<int, String>.named(3, "hello"); |
| + A<int, String> a4 = /*warning:InferableAllocation*/new A<int, dynamic>(3, "hello"); |
| + A<int, String> a5 = /*warning:InferableAllocation*/new A<dynamic, dynamic>.named(3, "hello"); |
| + } |
| + { |
| + A<int, String> a0 = /*warning:InferableAllocation*/new A("hello", 3); |
| + A<int, String> a1 = /*warning:InferableAllocation*/new A.named("hello", 3); |
| + } |
| + { |
| + A<int, String> a0 = /*$error*/new B("hello", 3); |
| + A<int, String> a1 = /*$error*/new B.named("hello", 3); |
| + A<int, String> a2 = new B<String, int>("hello", 3); |
| + A<int, String> a3 = new B<String, int>.named("hello", 3); |
| + A<int, String> a4 = /*warning:InferableAllocation*/new B<String, dynamic>("hello", 3); |
| + A<int, String> a5 = /*warning:InferableAllocation*/new B<dynamic, dynamic>.named("hello", 3); |
| + } |
| + { |
| + A<int, String> a0 = /*warning:InferableAllocation*/new B(3, "hello"); |
| + A<int, String> a1 = /*warning:InferableAllocation*/new B.named(3, "hello"); |
| + } |
| + { |
| + A<int, int> a0 = /*$error*/new C(3); |
| + A<int, int> a1 = /*$error*/new C.named(3); |
| + A<int, int> a2 = new C<int>(3); |
| + A<int, int> a3 = new C<int>.named(3); |
| + A<int, int> a4 = /*warning:InferableAllocation*/new C<dynamic>(3); |
| + A<int, int> a5 = /*warning:InferableAllocation*/new C<dynamic>.named(3); |
| + } |
| + { |
| + A<int, int> a0 = /*warning:InferableAllocation*/new C("hello"); |
| + A<int, int> a1 = /*warning:InferableAllocation*/new C.named("hello"); |
| + } |
| + { |
| + A<int, String> a0 = /*$error*/new D("hello"); |
| + A<int, String> a1 = /*$error*/new D.named("hello"); |
| + A<int, String> a2 = new D<int, String>("hello"); |
| + A<int, String> a3 = new D<String, String>.named("hello"); |
| + A<int, String> a4 = /*warning:InferableAllocation*/new D<num, dynamic>("hello"); |
| + A<int, String> a5 = /*warning:InferableAllocation*/new D<dynamic, dynamic>.named("hello"); |
| + } |
| + { |
| + A<int, String> a0 = /*warning:InferableAllocation*/new D(3); |
| + A<int, String> a1 = /*warning:InferableAllocation*/new D.named(3); |
| + } |
| + { // Currently we only allow variable constraints. Test that we reject. |
| + A<C<int>, String> a0 = /*warning:InferableAllocation*/new E("hello"); |
| + } |
| + } |
| + '''; |
| + testChecker({'/main.dart': mk("info:InferredTypeExact")}, |
| + inferDownwards: true); |
| + testChecker({'/main.dart': mk("warning:InferableAllocation")}, |
| + inferDownwards: false); |
| + }); |
| + |
| + test('downwards inference on list literals', () { |
| + String mk(String error) => ''' |
| + List<int> l0 = /*$error*/[]; |
| + List<int> l1 = /*$error*/[3]; |
| + List<int> l2 = /*warning:InferableLiteral*/["hello"]; |
| + List<int> l3 = /*warning:InferableLiteral*/["hello", 3]; |
|
vsm
2015/03/27 21:20:59
Perhaps some tests with variables / expressions in
|
| + |
| + List<dynamic> l0 = []; |
| + List<dynamic> l1 = [3]; |
| + List<dynamic> l2 = ["hello"]; |
| + List<dynamic> l3 = ["hello", 3]; |
| + |
| + List<int> l0 = /*warning:InferableLiteral*/<num>[]; |
| + List<int> l1 = /*warning:InferableLiteral*/<num>[3]; |
| + List<int> l2 = /*warning:InferableLiteral*/<num>[/*severe:StaticTypeError*/"hello"]; |
| + List<int> l3 = /*warning:InferableLiteral*/<num>[/*severe:StaticTypeError*/"hello", 3]; |
| + |
| + Iterable<int> i0 = /*$error*/[]; |
| + Iterable<int> i1 = /*$error*/[3]; |
| + Iterable<int> i2 = /*warning:InferableLiteral*/["hello"]; |
| + Iterable<int> i3 = /*warning:InferableLiteral*/["hello", 3]; |
| + |
| + const List<int> c0 = /*$error*/const []; |
| + const List<int> c1 = /*$error*/const [3]; |
| + const List<int> c2 = /*warning:InferableLiteral*/const ["hello"]; |
| + const List<int> c3 = /*warning:InferableLiteral*/const ["hello", 3]; |
| + '''; |
| + testChecker({'/main.dart': mk("info:InferredTypeLiteral")}, |
| + inferDownwards: true); |
| + testChecker({'/main.dart': mk("warning:InferableLiteral")}, |
| + inferDownwards: false); |
| + }); |
| + |
| + test('downwards inference on function arguments', () { |
| + String mk(String error) => ''' |
| + void f0(List<int> a) {}; |
| + void f1({List<int> a}) {}; |
| + f0(/*$error*/[]); |
| + f0(/*$error*/[3]); |
| + f0(/*warning:InferableLiteral*/["hello"]); |
| + f0(/*warning:InferableLiteral*/["hello", 3]); |
| + |
| + /// TODO(leafp): What's going on here? |
| + f1(a: /*pass should be $error*/[]); |
| + f1(a: /*pass should be $error*/[3]); |
| + f1(a: /*pass should be warning:InferableLiteral*/["hello"]); |
| + f1(a: /*pass should be warning:InferableLiteral*/["hello", 3]); |
| + |
| + '''; |
| + testChecker({'/main.dart': mk("info:InferredTypeLiteral")}, |
| + inferDownwards: true); |
| + testChecker({'/main.dart': mk("warning:InferableLiteral")}, |
| + inferDownwards: false); |
| + }); |
| + |
| + test('downwards inference on map literals', () { |
| + String mk(String error) => ''' |
| + Map<int, String> l0 = /*$error*/{}; |
| + Map<int, String> l1 = /*$error*/{3: "hello"}; |
| + Map<int, String> l2 = /*warning:InferableLiteral*/{"hello": "hello"}; |
| + Map<int, String> l3 = /*warning:InferableLiteral*/{3: 3}; |
| + Map<int, String> l4 = /*warning:InferableLiteral*/{3:"hello", "hello": 3}; |
| + |
| + Map<dynamic, dynamic> l0 = {}; |
| + Map<dynamic, dynamic> l1 = {3: "hello"}; |
| + Map<dynamic, dynamic> l2 = {"hello": "hello"}; |
| + Map<dynamic, dynamic> l3 = {3: 3}; |
| + Map<dynamic, dynamic> l4 = {3:"hello", "hello": 3}; |
| + |
| + Map<dynamic, String> l0 = /*$error*/{}; |
| + Map<dynamic, String> l1 = /*$error*/{3: "hello"}; |
| + Map<dynamic, String> l2 = /*$error*/{"hello": "hello"}; |
| + Map<dynamic, String> l3 = /*warning:InferableLiteral*/{3: 3}; |
| + Map<dynamic, String> l4 = /*warning:InferableLiteral*/{3:"hello", "hello": 3}; |
| + |
| + Map<int, dynamic> l0 = /*$error*/{}; |
| + Map<int, dynamic> l1 = /*$error*/{3: "hello"}; |
| + Map<int, dynamic> l2 = /*warning:InferableLiteral*/{"hello": "hello"}; |
| + Map<int, dynamic> l3 = /*$error*/{3: 3}; |
| + Map<int, dynamic> l3 = /*warning:InferableLiteral*/{3:"hello", "hello": 3}; |
| + |
| + Map<int, String> l0 = /*warning:InferableLiteral*/<num, dynamic>{}; |
| + Map<int, String> l1 = /*warning:InferableLiteral*/<num, dynamic>{3: "hello"}; |
| + Map<int, String> l3 = /*warning:InferableLiteral*/<num, dynamic>{3: 3}; |
| + |
| + const Map<int, String> l0 = /*$error*/const {}; |
| + const Map<int, String> l1 = /*$error*/const {3: "hello"}; |
| + const Map<int, String> l2 = /*warning:InferableLiteral*/const {"hello": "hello"}; |
| + const Map<int, String> l3 = /*warning:InferableLiteral*/const {3: 3}; |
| + const Map<int, String> l4 = /*warning:InferableLiteral*/const {3:"hello", "hello": 3}; |
| + '''; |
| + testChecker({'/main.dart': mk("info:InferredTypeLiteral")}, |
| + inferDownwards: true); |
| + testChecker({'/main.dart': mk("warning:InferableLiteral")}, |
| + inferDownwards: false); |
| + }); |
| } |