| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /// Tests for type inference. | 5 /// Tests for type inference. |
| 6 library dev_compiler.test.inferred_type_test; | 6 library dev_compiler.test.inferred_type_test; |
| 7 | 7 |
| 8 import 'package:test/test.dart'; | 8 import 'package:test/test.dart'; |
| 9 | 9 |
| 10 import '../testing.dart'; | 10 import '../testing.dart'; |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 x = "hi"; | 118 x = "hi"; |
| 119 y = /*severe:StaticTypeError*/"hi"; | 119 y = /*severe:StaticTypeError*/"hi"; |
| 120 A.x = "hi"; | 120 A.x = "hi"; |
| 121 A.y = /*severe:StaticTypeError*/"hi"; | 121 A.y = /*severe:StaticTypeError*/"hi"; |
| 122 new A().x2 = "hi"; | 122 new A().x2 = "hi"; |
| 123 new A().y2 = /*severe:StaticTypeError*/"hi"; | 123 new A().y2 = /*severe:StaticTypeError*/"hi"; |
| 124 } | 124 } |
| 125 ''' | 125 ''' |
| 126 }); | 126 }); |
| 127 | 127 |
| 128 testChecker( | 128 testChecker('infer from variables in non-cycle imports with flag', { |
| 129 'infer from variables in non-cycle imports with flag', | 129 '/a.dart': ''' |
| 130 { | |
| 131 '/a.dart': ''' | |
| 132 var x = 2; | 130 var x = 2; |
| 133 ''', | 131 ''', |
| 134 '/main.dart': ''' | 132 '/main.dart': ''' |
| 135 import 'a.dart'; | 133 import 'a.dart'; |
| 136 var y = x; | 134 var y = x; |
| 137 | 135 |
| 138 test1() { | 136 test1() { |
| 139 x = /*severe:StaticTypeError*/"hi"; | 137 x = /*severe:StaticTypeError*/"hi"; |
| 140 y = /*severe:StaticTypeError*/"hi"; | 138 y = /*severe:StaticTypeError*/"hi"; |
| 141 } | 139 } |
| 142 ''' | 140 ''' |
| 143 }, | 141 }); |
| 144 inferTransitively: true); | |
| 145 | 142 |
| 146 testChecker( | 143 testChecker('infer from variables in non-cycle imports with flag 2', { |
| 147 'infer from variables in non-cycle imports with flag 2', | 144 '/a.dart': ''' |
| 148 { | |
| 149 '/a.dart': ''' | |
| 150 class A { static var x = 2; } | 145 class A { static var x = 2; } |
| 151 ''', | 146 ''', |
| 152 '/main.dart': ''' | 147 '/main.dart': ''' |
| 153 import 'a.dart'; | 148 import 'a.dart'; |
| 154 class B { static var y = A.x; } | 149 class B { static var y = A.x; } |
| 155 | 150 |
| 156 test1() { | 151 test1() { |
| 157 A.x = /*severe:StaticTypeError*/"hi"; | 152 A.x = /*severe:StaticTypeError*/"hi"; |
| 158 B.y = /*severe:StaticTypeError*/"hi"; | 153 B.y = /*severe:StaticTypeError*/"hi"; |
| 159 } | 154 } |
| 160 ''' | 155 ''' |
| 161 }, | 156 }); |
| 162 inferTransitively: true); | |
| 163 | 157 |
| 164 testChecker( | 158 testChecker('infer from variables in cycle libs when flag is on', { |
| 165 'infer from variables in cycle libs when flag is on', | 159 '/a.dart': ''' |
| 166 { | |
| 167 '/a.dart': ''' | |
| 168 import 'main.dart'; | 160 import 'main.dart'; |
| 169 var x = 2; // ok to infer | 161 var x = 2; // ok to infer |
| 170 ''', | 162 ''', |
| 171 '/main.dart': ''' | 163 '/main.dart': ''' |
| 172 import 'a.dart'; | 164 import 'a.dart'; |
| 173 var y = x; // now ok :) | 165 var y = x; // now ok :) |
| 174 | 166 |
| 175 test1() { | 167 test1() { |
| 176 int t = 3; | 168 int t = 3; |
| 177 t = x; | 169 t = x; |
| 178 t = y; | 170 t = y; |
| 179 } | 171 } |
| 180 ''' | 172 ''' |
| 181 }, | 173 }); |
| 182 inferTransitively: true); | |
| 183 | 174 |
| 184 testChecker( | 175 testChecker('infer from variables in cycle libs when flag is on 2', { |
| 185 'infer from variables in cycle libs when flag is on 2', | 176 '/a.dart': ''' |
| 186 { | |
| 187 '/a.dart': ''' | |
| 188 import 'main.dart'; | 177 import 'main.dart'; |
| 189 class A { static var x = 2; } | 178 class A { static var x = 2; } |
| 190 ''', | 179 ''', |
| 191 '/main.dart': ''' | 180 '/main.dart': ''' |
| 192 import 'a.dart'; | 181 import 'a.dart'; |
| 193 class B { static var y = A.x; } | 182 class B { static var y = A.x; } |
| 194 | 183 |
| 195 test1() { | 184 test1() { |
| 196 int t = 3; | 185 int t = 3; |
| 197 t = A.x; | 186 t = A.x; |
| 198 t = B.y; | 187 t = B.y; |
| 199 } | 188 } |
| 200 ''' | 189 ''' |
| 201 }, | 190 }); |
| 202 inferTransitively: true); | |
| 203 | 191 |
| 204 testChecker( | 192 testChecker('can infer also from static and instance fields (flag on)', { |
| 205 'can infer also from static and instance fields (flag on)', | 193 '/a.dart': ''' |
| 206 { | |
| 207 '/a.dart': ''' | |
| 208 import 'b.dart'; | 194 import 'b.dart'; |
| 209 class A { | 195 class A { |
| 210 static final a1 = B.b1; | 196 static final a1 = B.b1; |
| 211 final a2 = new B().b2; | 197 final a2 = new B().b2; |
| 212 } | 198 } |
| 213 ''', | 199 ''', |
| 214 '/b.dart': ''' | 200 '/b.dart': ''' |
| 215 class B { | 201 class B { |
| 216 static final b1 = 1; | 202 static final b1 = 1; |
| 217 final b2 = 1; | 203 final b2 = 1; |
| 218 } | 204 } |
| 219 ''', | 205 ''', |
| 220 '/main.dart': ''' | 206 '/main.dart': ''' |
| 221 import "a.dart"; | 207 import "a.dart"; |
| 222 | 208 |
| 223 test1() { | 209 test1() { |
| 224 int x = 0; | 210 int x = 0; |
| 225 // inference in A now works. | 211 // inference in A now works. |
| 226 x = A.a1; | 212 x = A.a1; |
| 227 x = new A().a2; | 213 x = new A().a2; |
| 228 } | 214 } |
| 229 ''' | 215 ''' |
| 230 }, | 216 }); |
| 231 inferTransitively: true); | |
| 232 | 217 |
| 233 testChecker( | 218 testChecker('inference in cycles is deterministic', { |
| 234 'inference in cycles is deterministic', | 219 '/a.dart': ''' |
| 235 { | |
| 236 '/a.dart': ''' | |
| 237 import 'b.dart'; | 220 import 'b.dart'; |
| 238 class A { | 221 class A { |
| 239 static final a1 = B.b1; | 222 static final a1 = B.b1; |
| 240 final a2 = new B().b2; | 223 final a2 = new B().b2; |
| 241 } | 224 } |
| 242 ''', | 225 ''', |
| 243 '/b.dart': ''' | 226 '/b.dart': ''' |
| 244 class B { | 227 class B { |
| 245 static final b1 = 1; | 228 static final b1 = 1; |
| 246 final b2 = 1; | 229 final b2 = 1; |
| 247 } | 230 } |
| 248 ''', | 231 ''', |
| 249 '/c.dart': ''' | 232 '/c.dart': ''' |
| 250 import "main.dart"; // creates a cycle | 233 import "main.dart"; // creates a cycle |
| 251 | 234 |
| 252 class C { | 235 class C { |
| 253 static final c1 = 1; | 236 static final c1 = 1; |
| 254 final c2 = 1; | 237 final c2 = 1; |
| 255 } | 238 } |
| 256 ''', | 239 ''', |
| 257 '/e.dart': ''' | 240 '/e.dart': ''' |
| 258 import 'a.dart'; | 241 import 'a.dart'; |
| 259 part 'e2.dart'; | 242 part 'e2.dart'; |
| 260 | 243 |
| 261 class E { | 244 class E { |
| 262 static final e1 = 1; | 245 static final e1 = 1; |
| 263 static final e2 = F.f1; | 246 static final e2 = F.f1; |
| 264 static final e3 = A.a1; | 247 static final e3 = A.a1; |
| 265 final e4 = 1; | 248 final e4 = 1; |
| 266 final e5 = new F().f2; | 249 final e5 = new F().f2; |
| 267 final e6 = new A().a2; | 250 final e6 = new A().a2; |
| 268 } | 251 } |
| 269 ''', | 252 ''', |
| 270 '/f.dart': ''' | 253 '/f.dart': ''' |
| 271 part 'f2.dart'; | 254 part 'f2.dart'; |
| 272 ''', | 255 ''', |
| 273 '/e2.dart': ''' | 256 '/e2.dart': ''' |
| 274 class F { | 257 class F { |
| 275 static final f1 = 1; | 258 static final f1 = 1; |
| 276 final f2 = 1; | 259 final f2 = 1; |
| 277 } | 260 } |
| 278 ''', | 261 ''', |
| 279 '/main.dart': ''' | 262 '/main.dart': ''' |
| 280 import "a.dart"; | 263 import "a.dart"; |
| 281 import "c.dart"; | 264 import "c.dart"; |
| 282 import "e.dart"; | 265 import "e.dart"; |
| 283 | 266 |
| 284 class D { | 267 class D { |
| 285 static final d1 = A.a1 + 1; | 268 static final d1 = A.a1 + 1; |
| 286 static final d2 = C.c1 + 1; | 269 static final d2 = C.c1 + 1; |
| 287 final d3 = new A().a2; | 270 final d3 = new A().a2; |
| 288 final d4 = new C().c2; | 271 final d4 = new C().c2; |
| 289 } | 272 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 308 x = E.e1; | 291 x = E.e1; |
| 309 x = E.e2; | 292 x = E.e2; |
| 310 x = E.e3; | 293 x = E.e3; |
| 311 x = new E().e4; | 294 x = new E().e4; |
| 312 x = /*info:DynamicCast*/new E().e5; | 295 x = /*info:DynamicCast*/new E().e5; |
| 313 x = new E().e6; | 296 x = new E().e6; |
| 314 x = F.f1; | 297 x = F.f1; |
| 315 x = new F().f2; | 298 x = new F().f2; |
| 316 } | 299 } |
| 317 ''' | 300 ''' |
| 318 }, | 301 }); |
| 319 inferTransitively: true); | |
| 320 | 302 |
| 321 testChecker( | 303 testChecker( |
| 322 'infer from complex expressions if the outer-most value is precise', { | 304 'infer from complex expressions if the outer-most value is precise', { |
| 323 '/main.dart': ''' | 305 '/main.dart': ''' |
| 324 class A { int x; B operator+(other) {} } | 306 class A { int x; B operator+(other) {} } |
| 325 class B extends A { B(ignore); } | 307 class B extends A { B(ignore); } |
| 326 var a = new A(); | 308 var a = new A(); |
| 327 // Note: it doesn't matter that some of these refer to 'x'. | 309 // Note: it doesn't matter that some of these refer to 'x'. |
| 328 var b = new B(x); // allocations | 310 var b = new B(x); // allocations |
| 329 var c1 = [x]; // list literals | 311 var c1 = [x]; // list literals |
| (...skipping 29 matching lines...) Expand all Loading... |
| 359 h = new B(); | 341 h = new B(); |
| 360 i = false; | 342 i = false; |
| 361 j = new B(); | 343 j = new B(); |
| 362 j = /*severe:StaticTypeError*/false; | 344 j = /*severe:StaticTypeError*/false; |
| 363 j = /*severe:StaticTypeError*/[]; | 345 j = /*severe:StaticTypeError*/[]; |
| 364 } | 346 } |
| 365 ''' | 347 ''' |
| 366 }); | 348 }); |
| 367 | 349 |
| 368 // but flags can enable this behavior. | 350 // but flags can enable this behavior. |
| 369 testChecker( | 351 testChecker('infer if complex expressions read possibly inferred field', { |
| 370 'infer if complex expressions read possibly inferred field', | 352 '/a.dart': ''' |
| 371 { | |
| 372 '/a.dart': ''' | |
| 373 class A { | 353 class A { |
| 374 var x = 3; | 354 var x = 3; |
| 375 } | 355 } |
| 376 ''', | 356 ''', |
| 377 '/main.dart': ''' | 357 '/main.dart': ''' |
| 378 import 'a.dart'; | 358 import 'a.dart'; |
| 379 class B { | 359 class B { |
| 380 var y = 3; | 360 var y = 3; |
| 381 } | 361 } |
| 382 final t1 = new A(); | 362 final t1 = new A(); |
| 383 final t2 = new A().x; | 363 final t2 = new A().x; |
| 384 final t3 = new B(); | 364 final t3 = new B(); |
| 385 final t4 = new B().y; | 365 final t4 = new B().y; |
| 386 | 366 |
| 387 test1() { | 367 test1() { |
| 388 int i = 0; | 368 int i = 0; |
| 389 A a; | 369 A a; |
| 390 B b; | 370 B b; |
| 391 a = t1; | 371 a = t1; |
| 392 i = t2; | 372 i = t2; |
| 393 b = t3; | 373 b = t3; |
| 394 i = /*info:DynamicCast*/t4; | 374 i = /*info:DynamicCast*/t4; |
| 395 i = new B().y; // B.y was inferred though | 375 i = new B().y; // B.y was inferred though |
| 396 } | 376 } |
| 397 ''' | 377 ''' |
| 398 }, | 378 }); |
| 399 inferTransitively: true); | |
| 400 | 379 |
| 401 group('infer types on loop indices', () { | 380 group('infer types on loop indices', () { |
| 402 testChecker('foreach loop', { | 381 testChecker('foreach loop', { |
| 403 '/main.dart': ''' | 382 '/main.dart': ''' |
| 404 class Foo { | 383 class Foo { |
| 405 int bar = 42; | 384 int bar = 42; |
| 406 } | 385 } |
| 407 | 386 |
| 408 test() { | 387 test() { |
| 409 var list = <Foo>[]; | 388 var list = <Foo>[]; |
| (...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 848 s = /*severe:StaticTypeError*/new B().w; | 827 s = /*severe:StaticTypeError*/new B().w; |
| 849 | 828 |
| 850 i = /*info:DynamicCast*/new B().x; | 829 i = /*info:DynamicCast*/new B().x; |
| 851 i = new B().y; | 830 i = new B().y; |
| 852 i = /*severe:StaticTypeError*/new B().z; | 831 i = /*severe:StaticTypeError*/new B().z; |
| 853 i = new B().w; | 832 i = new B().w; |
| 854 } | 833 } |
| 855 ''' | 834 ''' |
| 856 }); | 835 }); |
| 857 | 836 |
| 858 testChecker( | 837 testChecker('infer consts transitively', { |
| 859 'infer consts transitively', | 838 '/b.dart': ''' |
| 860 { | |
| 861 '/b.dart': ''' | |
| 862 const b1 = 2; | 839 const b1 = 2; |
| 863 ''', | 840 ''', |
| 864 '/a.dart': ''' | 841 '/a.dart': ''' |
| 865 import 'main.dart'; | 842 import 'main.dart'; |
| 866 import 'b.dart'; | 843 import 'b.dart'; |
| 867 const a1 = m2; | 844 const a1 = m2; |
| 868 const a2 = b1; | 845 const a2 = b1; |
| 869 ''', | 846 ''', |
| 870 '/main.dart': ''' | 847 '/main.dart': ''' |
| 871 import 'a.dart'; | 848 import 'a.dart'; |
| 872 const m1 = a1; | 849 const m1 = a1; |
| 873 const m2 = a2; | 850 const m2 = a2; |
| 874 | 851 |
| 875 foo() { | 852 foo() { |
| 876 int i; | 853 int i; |
| 877 i = m1; | 854 i = m1; |
| 878 } | 855 } |
| 879 ''' | 856 ''' |
| 880 }, | 857 }); |
| 881 inferTransitively: true); | |
| 882 | 858 |
| 883 testChecker( | 859 testChecker('infer statics transitively', { |
| 884 'infer statics transitively', | 860 '/b.dart': ''' |
| 885 { | |
| 886 '/b.dart': ''' | |
| 887 final b1 = 2; | 861 final b1 = 2; |
| 888 ''', | 862 ''', |
| 889 '/a.dart': ''' | 863 '/a.dart': ''' |
| 890 import 'main.dart'; | 864 import 'main.dart'; |
| 891 import 'b.dart'; | 865 import 'b.dart'; |
| 892 final a1 = m2; | 866 final a1 = m2; |
| 893 class A { | 867 class A { |
| 894 static final a2 = b1; | 868 static final a2 = b1; |
| 895 } | 869 } |
| 896 ''', | 870 ''', |
| 897 '/main.dart': ''' | 871 '/main.dart': ''' |
| 898 import 'a.dart'; | 872 import 'a.dart'; |
| 899 final m1 = a1; | 873 final m1 = a1; |
| 900 final m2 = A.a2; | 874 final m2 = A.a2; |
| 901 | 875 |
| 902 foo() { | 876 foo() { |
| 903 int i; | 877 int i; |
| 904 i = m1; | 878 i = m1; |
| 905 } | 879 } |
| 906 ''' | 880 ''' |
| 907 }, | 881 }); |
| 908 inferTransitively: true); | |
| 909 | 882 |
| 910 testChecker( | 883 testChecker('infer statics transitively 2', { |
| 911 'infer statics transitively 2', | 884 '/main.dart': ''' |
| 912 { | |
| 913 '/main.dart': ''' | |
| 914 const x1 = 1; | 885 const x1 = 1; |
| 915 final x2 = 1; | 886 final x2 = 1; |
| 916 final y1 = x1; | 887 final y1 = x1; |
| 917 final y2 = x2; | 888 final y2 = x2; |
| 918 | 889 |
| 919 foo() { | 890 foo() { |
| 920 int i; | 891 int i; |
| 921 i = y1; | 892 i = y1; |
| 922 i = y2; | 893 i = y2; |
| 923 } | 894 } |
| 924 ''' | 895 ''' |
| 925 }, | 896 }); |
| 926 inferTransitively: true); | |
| 927 | 897 |
| 928 testChecker( | 898 testChecker('infer statics transitively 3', { |
| 929 'infer statics transitively 3', | 899 '/a.dart': ''' |
| 930 { | |
| 931 '/a.dart': ''' | |
| 932 const a1 = 3; | 900 const a1 = 3; |
| 933 const a2 = 4; | 901 const a2 = 4; |
| 934 class A { | 902 class A { |
| 935 a3; | 903 a3; |
| 936 } | 904 } |
| 937 ''', | 905 ''', |
| 938 '/main.dart': ''' | 906 '/main.dart': ''' |
| 939 import 'a.dart' show a1, A; | 907 import 'a.dart' show a1, A; |
| 940 import 'a.dart' as p show a2, A; | 908 import 'a.dart' as p show a2, A; |
| 941 const t1 = 1; | 909 const t1 = 1; |
| 942 const t2 = t1; | 910 const t2 = t1; |
| 943 const t3 = a1; | 911 const t3 = a1; |
| 944 const t4 = p.a2; | 912 const t4 = p.a2; |
| 945 const t5 = A.a3; | 913 const t5 = A.a3; |
| 946 const t6 = p.A.a3; | 914 const t6 = p.A.a3; |
| 947 | 915 |
| 948 foo() { | 916 foo() { |
| 949 int i; | 917 int i; |
| 950 i = t1; | 918 i = t1; |
| 951 i = t2; | 919 i = t2; |
| 952 i = t3; | 920 i = t3; |
| 953 i = t4; | 921 i = t4; |
| 954 } | 922 } |
| 955 ''' | 923 ''' |
| 956 }, | 924 }); |
| 957 inferTransitively: true); | |
| 958 | 925 |
| 959 testChecker( | 926 testChecker('infer statics with method invocations', { |
| 960 'infer statics with method invocations', | 927 '/a.dart': ''' |
| 961 { | |
| 962 '/a.dart': ''' | |
| 963 m3(String a, String b, [a1,a2]) {} | 928 m3(String a, String b, [a1,a2]) {} |
| 964 ''', | 929 ''', |
| 965 '/main.dart': ''' | 930 '/main.dart': ''' |
| 966 import 'a.dart'; | 931 import 'a.dart'; |
| 967 class T { | 932 class T { |
| 968 static final T foo = m1(m2(m3('', ''))); | 933 static final T foo = m1(m2(m3('', ''))); |
| 969 static T m1(String m) { return null; } | 934 static T m1(String m) { return null; } |
| 970 static String m2(e) { return ''; } | 935 static String m2(e) { return ''; } |
| 971 } | 936 } |
| 972 | 937 |
| 973 | 938 |
| 974 ''' | 939 ''' |
| 975 }, | 940 }); |
| 976 inferTransitively: true); | |
| 977 | 941 |
| 978 testChecker( | 942 testChecker('downwards inference: miscellaneous', { |
| 979 'downwards inference: miscellaneous', | 943 '/main.dart': ''' |
| 980 { | |
| 981 '/main.dart': ''' | |
| 982 typedef (T x); | 944 typedef (T x); |
| 983 class A<T> { | 945 class A<T> { |
| 984 Function2<T> x; | 946 Function2<T> x; |
| 985 A(this.x); | 947 A(this.x); |
| 986 } | 948 } |
| 987 void main() { | 949 void main() { |
| 988 { // Variables, nested literals | 950 { // Variables, nested literals |
| 989 var x = "hello"; | 951 var x = "hello"; |
| 990 var y = 3; | 952 var y = 3; |
| 991 void f(List<Map<int, String>> l) {}; | 953 void f(List<Map<int, String>> l) {}; |
| 992 f(/*info:InferredTypeLiteral*/[{y: x}]); | 954 f(/*info:InferredTypeLiteral*/[{y: x}]); |
| 993 } | 955 } |
| 994 { | 956 { |
| 995 int f(int x) {}; | 957 int f(int x) {}; |
| 996 A<int> a = /*info:InferredTypeAllocation*/new A(f); | 958 A<int> a = /*info:InferredTypeAllocation*/new A(f); |
| 997 } | 959 } |
| 998 } | 960 } |
| 999 ''' | 961 ''' |
| 1000 }, | 962 }); |
| 1001 inferDownwards: true); | |
| 1002 | 963 |
| 1003 group('downwards inference on instance creations', () { | 964 group('downwards inference on instance creations', () { |
| 1004 String mk(String info) => ''' | 965 String info = 'info:InferredTypeAllocation'; |
| 966 String code = ''' |
| 1005 class A<S, T> { | 967 class A<S, T> { |
| 1006 S x; | 968 S x; |
| 1007 T y; | 969 T y; |
| 1008 A(this.x, this.y); | 970 A(this.x, this.y); |
| 1009 A.named(this.x, this.y); | 971 A.named(this.x, this.y); |
| 1010 } | 972 } |
| 1011 | 973 |
| 1012 class B<S, T> extends A<T, S> { | 974 class B<S, T> extends A<T, S> { |
| 1013 B(S y, T x) : super(x, y); | 975 B(S y, T x) : super(x, y); |
| 1014 B.named(S y, T x) : super.named(x, y); | 976 B.named(S y, T x) : super.named(x, y); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1088 { // Check named and optional arguments | 1050 { // Check named and optional arguments |
| 1089 A<int, String> a0 = /*$info*/new F(3, "hello", a: [3], b: ["hello"]); | 1051 A<int, String> a0 = /*$info*/new F(3, "hello", a: [3], b: ["hello"]); |
| 1090 A<int, String> a1 = /*severe:StaticTypeError*/new F(3, "hello", a: ["h
ello"], b:[3]); | 1052 A<int, String> a1 = /*severe:StaticTypeError*/new F(3, "hello", a: ["h
ello"], b:[3]); |
| 1091 A<int, String> a2 = /*$info*/new F.named(3, "hello", 3, "hello"); | 1053 A<int, String> a2 = /*$info*/new F.named(3, "hello", 3, "hello"); |
| 1092 A<int, String> a3 = /*$info*/new F.named(3, "hello"); | 1054 A<int, String> a3 = /*$info*/new F.named(3, "hello"); |
| 1093 A<int, String> a4 = /*severe:StaticTypeError*/new F.named(3, "hello",
"hello", 3); | 1055 A<int, String> a4 = /*severe:StaticTypeError*/new F.named(3, "hello",
"hello", 3); |
| 1094 A<int, String> a5 = /*severe:StaticTypeError*/new F.named(3, "hello",
"hello"); | 1056 A<int, String> a5 = /*severe:StaticTypeError*/new F.named(3, "hello",
"hello"); |
| 1095 } | 1057 } |
| 1096 } | 1058 } |
| 1097 '''; | 1059 '''; |
| 1098 testChecker( | 1060 testChecker('infer downwards', {'/main.dart': code}); |
| 1099 'infer downwards', {'/main.dart': mk("info:InferredTypeAllocation")}, | |
| 1100 inferDownwards: true); | |
| 1101 testChecker( | |
| 1102 'no infer downwards', {'/main.dart': mk("severe:StaticTypeError")}, | |
| 1103 inferDownwards: false); | |
| 1104 }); | 1061 }); |
| 1105 | 1062 |
| 1106 group('downwards inference on list literals', () { | 1063 group('downwards inference on list literals', () { |
| 1107 String mk(String info) => ''' | 1064 String info = "info:InferredTypeLiteral"; |
| 1065 String code = ''' |
| 1108 void foo([List<String> list1 = /*$info*/const [], | 1066 void foo([List<String> list1 = /*$info*/const [], |
| 1109 List<String> list2 = /*severe:StaticTypeError*/const [42]]) { | 1067 List<String> list2 = /*severe:StaticTypeError*/const [42]]) { |
| 1110 } | 1068 } |
| 1111 | 1069 |
| 1112 void main() { | 1070 void main() { |
| 1113 { | 1071 { |
| 1114 List<int> l0 = /*$info*/[]; | 1072 List<int> l0 = /*$info*/[]; |
| 1115 List<int> l1 = /*$info*/[3]; | 1073 List<int> l1 = /*$info*/[3]; |
| 1116 List<int> l2 = /*severe:StaticTypeError*/["hello"]; | 1074 List<int> l2 = /*severe:StaticTypeError*/["hello"]; |
| 1117 List<int> l3 = /*severe:StaticTypeError*/["hello", 3]; | 1075 List<int> l3 = /*severe:StaticTypeError*/["hello", 3]; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1135 Iterable<int> i3 = /*severe:StaticTypeError*/["hello", 3]; | 1093 Iterable<int> i3 = /*severe:StaticTypeError*/["hello", 3]; |
| 1136 } | 1094 } |
| 1137 { | 1095 { |
| 1138 const List<int> c0 = /*$info*/const []; | 1096 const List<int> c0 = /*$info*/const []; |
| 1139 const List<int> c1 = /*$info*/const [3]; | 1097 const List<int> c1 = /*$info*/const [3]; |
| 1140 const List<int> c2 = /*severe:StaticTypeError*/const ["hello"]; | 1098 const List<int> c2 = /*severe:StaticTypeError*/const ["hello"]; |
| 1141 const List<int> c3 = /*severe:StaticTypeError*/const ["hello", 3]; | 1099 const List<int> c3 = /*severe:StaticTypeError*/const ["hello", 3]; |
| 1142 } | 1100 } |
| 1143 } | 1101 } |
| 1144 '''; | 1102 '''; |
| 1145 testChecker( | 1103 testChecker('infer downwards', {'/main.dart': code}); |
| 1146 'infer downwards', {'/main.dart': mk("info:InferredTypeLiteral")}, | |
| 1147 inferDownwards: true); | |
| 1148 testChecker( | |
| 1149 'no infer downwards', {'/main.dart': mk("severe:StaticTypeError")}, | |
| 1150 inferDownwards: false); | |
| 1151 }); | 1104 }); |
| 1152 | 1105 |
| 1153 group('downwards inference on function arguments', () { | 1106 group('downwards inference on function arguments', () { |
| 1154 String mk(String info) => ''' | 1107 String info = "info:InferredTypeLiteral"; |
| 1108 String code = ''' |
| 1155 void f0(List<int> a) {}; | 1109 void f0(List<int> a) {}; |
| 1156 void f1({List<int> a}) {}; | 1110 void f1({List<int> a}) {}; |
| 1157 void f2(Iterable<int> a) {}; | 1111 void f2(Iterable<int> a) {}; |
| 1158 void f3(Iterable<Iterable<int>> a) {}; | 1112 void f3(Iterable<Iterable<int>> a) {}; |
| 1159 void f4({Iterable<Iterable<int>> a}) {}; | 1113 void f4({Iterable<Iterable<int>> a}) {}; |
| 1160 void main() { | 1114 void main() { |
| 1161 f0(/*$info*/[]); | 1115 f0(/*$info*/[]); |
| 1162 f0(/*$info*/[3]); | 1116 f0(/*$info*/[3]); |
| 1163 f0(/*severe:StaticTypeError*/["hello"]); | 1117 f0(/*severe:StaticTypeError*/["hello"]); |
| 1164 f0(/*severe:StaticTypeError*/["hello", 3]); | 1118 f0(/*severe:StaticTypeError*/["hello", 3]); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1177 f3(/*$info*/[[3]]); | 1131 f3(/*$info*/[[3]]); |
| 1178 f3(/*severe:StaticTypeError*/[["hello"]]); | 1132 f3(/*severe:StaticTypeError*/[["hello"]]); |
| 1179 f3(/*severe:StaticTypeError*/[["hello"], [3]]); | 1133 f3(/*severe:StaticTypeError*/[["hello"], [3]]); |
| 1180 | 1134 |
| 1181 f4(a: /*$info*/[]); | 1135 f4(a: /*$info*/[]); |
| 1182 f4(a: /*$info*/[[3]]); | 1136 f4(a: /*$info*/[[3]]); |
| 1183 f4(a: /*severe:StaticTypeError*/[["hello"]]); | 1137 f4(a: /*severe:StaticTypeError*/[["hello"]]); |
| 1184 f4(a: /*severe:StaticTypeError*/[["hello"], [3]]); | 1138 f4(a: /*severe:StaticTypeError*/[["hello"], [3]]); |
| 1185 } | 1139 } |
| 1186 '''; | 1140 '''; |
| 1187 testChecker( | 1141 testChecker('infer downwards', {'/main.dart': code}); |
| 1188 'infer downwards', {'/main.dart': mk("info:InferredTypeLiteral")}, | |
| 1189 inferDownwards: true); | |
| 1190 testChecker( | |
| 1191 'no infer downwards', {'/main.dart': mk("severe:StaticTypeError")}, | |
| 1192 inferDownwards: false); | |
| 1193 }); | 1142 }); |
| 1194 | 1143 |
| 1195 group('downwards inference on map literals', () { | 1144 group('downwards inference on map literals', () { |
| 1196 String mk(String info) => ''' | 1145 String info = "info:InferredTypeLiteral"; |
| 1146 String code = ''' |
| 1197 void foo([Map<int, String> m1 = /*$info*/const {1: "hello"}, | 1147 void foo([Map<int, String> m1 = /*$info*/const {1: "hello"}, |
| 1198 Map<int, String> m1 = /*severe:StaticTypeError*/const {"hello":
"world"}]) { | 1148 Map<int, String> m1 = /*severe:StaticTypeError*/const {"hello":
"world"}]) { |
| 1199 } | 1149 } |
| 1200 void main() { | 1150 void main() { |
| 1201 { | 1151 { |
| 1202 Map<int, String> l0 = /*$info*/{}; | 1152 Map<int, String> l0 = /*$info*/{}; |
| 1203 Map<int, String> l1 = /*$info*/{3: "hello"}; | 1153 Map<int, String> l1 = /*$info*/{3: "hello"}; |
| 1204 Map<int, String> l2 = /*severe:StaticTypeError*/{"hello": "hello"}; | 1154 Map<int, String> l2 = /*severe:StaticTypeError*/{"hello": "hello"}; |
| 1205 Map<int, String> l3 = /*severe:StaticTypeError*/{3: 3}; | 1155 Map<int, String> l3 = /*severe:StaticTypeError*/{3: 3}; |
| 1206 Map<int, String> l4 = /*severe:StaticTypeError*/{3:"hello", "hello": 3
}; | 1156 Map<int, String> l4 = /*severe:StaticTypeError*/{3:"hello", "hello": 3
}; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1233 } | 1183 } |
| 1234 { | 1184 { |
| 1235 const Map<int, String> l0 = /*$info*/const {}; | 1185 const Map<int, String> l0 = /*$info*/const {}; |
| 1236 const Map<int, String> l1 = /*$info*/const {3: "hello"}; | 1186 const Map<int, String> l1 = /*$info*/const {3: "hello"}; |
| 1237 const Map<int, String> l2 = /*severe:StaticTypeError*/const {"hello":
"hello"}; | 1187 const Map<int, String> l2 = /*severe:StaticTypeError*/const {"hello":
"hello"}; |
| 1238 const Map<int, String> l3 = /*severe:StaticTypeError*/const {3: 3}; | 1188 const Map<int, String> l3 = /*severe:StaticTypeError*/const {3: 3}; |
| 1239 const Map<int, String> l4 = /*severe:StaticTypeError*/const {3:"hello"
, "hello": 3}; | 1189 const Map<int, String> l4 = /*severe:StaticTypeError*/const {3:"hello"
, "hello": 3}; |
| 1240 } | 1190 } |
| 1241 } | 1191 } |
| 1242 '''; | 1192 '''; |
| 1243 testChecker( | 1193 testChecker('infer downwards', {'/main.dart': code}); |
| 1244 'infer downwards', {'/main.dart': mk("info:InferredTypeLiteral")}, | |
| 1245 inferDownwards: true); | |
| 1246 testChecker( | |
| 1247 'no infer downwards', {'/main.dart': mk("severe:StaticTypeError")}, | |
| 1248 inferDownwards: false); | |
| 1249 }); | 1194 }); |
| 1250 | 1195 |
| 1251 testChecker( | 1196 testChecker('downwards inference on function expressions', { |
| 1252 'downwards inference on function expressions', | 1197 '/main.dart': ''' |
| 1253 { | |
| 1254 '/main.dart': ''' | |
| 1255 typedef T Function2<S, T>(S x); | 1198 typedef T Function2<S, T>(S x); |
| 1256 | 1199 |
| 1257 void main () { | 1200 void main () { |
| 1258 { | 1201 { |
| 1259 Function2<int, String> l0 = (int x) => null; | 1202 Function2<int, String> l0 = (int x) => null; |
| 1260 Function2<int, String> l1 = (int x) => "hello"; | 1203 Function2<int, String> l1 = (int x) => "hello"; |
| 1261 Function2<int, String> l2 = /*severe:StaticTypeError*/(String x) => "h
ello"; | 1204 Function2<int, String> l2 = /*severe:StaticTypeError*/(String x) => "h
ello"; |
| 1262 Function2<int, String> l3 = /*severe:StaticTypeError*/(int x) => 3; | 1205 Function2<int, String> l3 = /*severe:StaticTypeError*/(int x) => 3; |
| 1263 Function2<int, String> l4 = /*warning:UninferredClosure should be seve
re:StaticTypeError*/(int x) {return 3}; | 1206 Function2<int, String> l4 = /*warning:UninferredClosure should be seve
re:StaticTypeError*/(int x) {return 3}; |
| 1264 } | 1207 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1277 } | 1220 } |
| 1278 { | 1221 { |
| 1279 Function2<int, int> l0 = /*info:InferredTypeClosure*/(x) => x; | 1222 Function2<int, int> l0 = /*info:InferredTypeClosure*/(x) => x; |
| 1280 Function2<int, int> l1 = /*info:InferredTypeClosure*/(x) => /*info:Dyn
amicInvoke should be pass*/x+1; | 1223 Function2<int, int> l1 = /*info:InferredTypeClosure*/(x) => /*info:Dyn
amicInvoke should be pass*/x+1; |
| 1281 Function2<int, String> l2 = /*info:InferredTypeClosure should be sever
e:StaticTypeError*/(x) => x; | 1224 Function2<int, String> l2 = /*info:InferredTypeClosure should be sever
e:StaticTypeError*/(x) => x; |
| 1282 Function2<int, String> l3 = /*info:InferredTypeClosure should be sever
e:StaticTypeError*/(x) => /*info:DynamicInvoke should be pass*/x.substring(3); | 1225 Function2<int, String> l3 = /*info:InferredTypeClosure should be sever
e:StaticTypeError*/(x) => /*info:DynamicInvoke should be pass*/x.substring(3); |
| 1283 Function2<String, String> l4 = /*info:InferredTypeClosure*/(x) => /*in
fo:DynamicInvoke should be pass*/x.substring(3); | 1226 Function2<String, String> l4 = /*info:InferredTypeClosure*/(x) => /*in
fo:DynamicInvoke should be pass*/x.substring(3); |
| 1284 } | 1227 } |
| 1285 } | 1228 } |
| 1286 ''' | 1229 ''' |
| 1287 }, | 1230 }); |
| 1288 inferDownwards: true); | |
| 1289 | 1231 |
| 1290 testChecker('inferred initializing formal checks default value', { | 1232 testChecker('inferred initializing formal checks default value', { |
| 1291 '/main.dart': ''' | 1233 '/main.dart': ''' |
| 1292 class Foo { | 1234 class Foo { |
| 1293 var x = 1; | 1235 var x = 1; |
| 1294 Foo([this.x = /*severe:StaticTypeError*/"1"]); | 1236 Foo([this.x = /*severe:StaticTypeError*/"1"]); |
| 1295 }''' | 1237 }''' |
| 1296 }); | 1238 }); |
| 1297 | 1239 |
| 1298 group('quasi-generics', () { | 1240 group('quasi-generics', () { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1340 main() { | 1282 main() { |
| 1341 Iterable<Future<int>> list = <int>[1, 2, 3].map(make); | 1283 Iterable<Future<int>> list = <int>[1, 2, 3].map(make); |
| 1342 Future<List<int>> results = Future.wait(list); | 1284 Future<List<int>> results = Future.wait(list); |
| 1343 Future<String> results2 = results.then((List<int> list) | 1285 Future<String> results2 = results.then((List<int> list) |
| 1344 => list.fold('', (String x, int y) => x + y.toString())); | 1286 => list.fold('', (String x, int y) => x + y.toString())); |
| 1345 } | 1287 } |
| 1346 ''' | 1288 ''' |
| 1347 }); | 1289 }); |
| 1348 }); | 1290 }); |
| 1349 } | 1291 } |
| OLD | NEW |