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 /// General type checking tests | 5 /// General type checking tests |
6 library dev_compiler.test.checker_test; | 6 library dev_compiler.test.checker_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 25 matching lines...) Expand all Loading... |
36 _v = /*info:InferredType should be pass*/(isValidKey != null) ? _v
: ((v) => true); | 36 _v = /*info:InferredType should be pass*/(isValidKey != null) ? _v
: ((v) => true); |
37 } | 37 } |
38 } | 38 } |
39 void main() { | 39 void main() { |
40 Object obj = 42; | 40 Object obj = 42; |
41 dynamic dyn = 42; | 41 dynamic dyn = 42; |
42 int i = 42; | 42 int i = 42; |
43 | 43 |
44 // Check the boolean conversion of the condition. | 44 // Check the boolean conversion of the condition. |
45 print((/*severe:StaticTypeError*/i) ? false : true); | 45 print((/*severe:StaticTypeError*/i) ? false : true); |
46 print((/*warning:DownCastImplicit*/obj) ? false : true); | 46 print((/*info:DownCastImplicit*/obj) ? false : true); |
47 print((/*info:DynamicCast*/dyn) ? false : true); | 47 print((/*info:DynamicCast*/dyn) ? false : true); |
48 } | 48 } |
49 ''' | 49 ''' |
50 }); | 50 }); |
51 | 51 |
52 testChecker('if/for/do/while statements use boolean conversion', { | 52 testChecker('if/for/do/while statements use boolean conversion', { |
53 '/main.dart': ''' | 53 '/main.dart': ''' |
54 main() { | 54 main() { |
55 dynamic d = 42; | 55 dynamic d = 42; |
56 Object obj = 42; | 56 Object obj = 42; |
57 int i = 42; | 57 int i = 42; |
58 bool b = false; | 58 bool b = false; |
59 | 59 |
60 if (b) {} | 60 if (b) {} |
61 if (/*info:DynamicCast*/dyn) {} | 61 if (/*info:DynamicCast*/dyn) {} |
62 if (/*warning:DownCastImplicit*/obj) {} | 62 if (/*info:DownCastImplicit*/obj) {} |
63 if (/*severe:StaticTypeError*/i) {} | 63 if (/*severe:StaticTypeError*/i) {} |
64 | 64 |
65 while (b) {} | 65 while (b) {} |
66 while (/*info:DynamicCast*/dyn) {} | 66 while (/*info:DynamicCast*/dyn) {} |
67 while (/*warning:DownCastImplicit*/obj) {} | 67 while (/*info:DownCastImplicit*/obj) {} |
68 while (/*severe:StaticTypeError*/i) {} | 68 while (/*severe:StaticTypeError*/i) {} |
69 | 69 |
70 do {} while (b); | 70 do {} while (b); |
71 do {} while (/*info:DynamicCast*/dyn); | 71 do {} while (/*info:DynamicCast*/dyn); |
72 do {} while (/*warning:DownCastImplicit*/obj); | 72 do {} while (/*info:DownCastImplicit*/obj); |
73 do {} while (/*severe:StaticTypeError*/i); | 73 do {} while (/*severe:StaticTypeError*/i); |
74 | 74 |
75 for (;b;) {} | 75 for (;b;) {} |
76 for (;/*info:DynamicCast*/dyn;) {} | 76 for (;/*info:DynamicCast*/dyn;) {} |
77 for (;/*warning:DownCastImplicit*/obj;) {} | 77 for (;/*info:DownCastImplicit*/obj;) {} |
78 for (;/*severe:StaticTypeError*/i;) {} | 78 for (;/*severe:StaticTypeError*/i;) {} |
79 } | 79 } |
80 ''' | 80 ''' |
81 }); | 81 }); |
82 | 82 |
83 testChecker('dynamic invocation', { | 83 testChecker('dynamic invocation', { |
84 '/main.dart': ''' | 84 '/main.dart': ''' |
85 | 85 |
86 class A { | 86 class A { |
87 dynamic call(dynamic x) => x; | 87 dynamic call(dynamic x) => x; |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 | 231 |
232 void main() { | 232 void main() { |
233 int /*severe:InvalidVariableDeclaration*/x; | 233 int /*severe:InvalidVariableDeclaration*/x; |
234 double /*severe:InvalidVariableDeclaration*/y; | 234 double /*severe:InvalidVariableDeclaration*/y; |
235 num z; | 235 num z; |
236 bool b; | 236 bool b; |
237 | 237 |
238 // int is non-nullable | 238 // int is non-nullable |
239 x = /*severe:StaticTypeError*/null; | 239 x = /*severe:StaticTypeError*/null; |
240 x = 42; | 240 x = 42; |
241 x = /*warning:DownCastImplicit*/z; | 241 x = /*info:DownCastImplicit*/z; |
242 | 242 |
243 // double is non-nullable | 243 // double is non-nullable |
244 y = /*severe:StaticTypeError*/null; | 244 y = /*severe:StaticTypeError*/null; |
245 y = /*severe:StaticTypeError*/42; | 245 y = /*severe:StaticTypeError*/42; |
246 y = 42.0; | 246 y = 42.0; |
247 y = /*warning:DownCastImplicit*/z; | 247 y = /*info:DownCastImplicit*/z; |
248 | 248 |
249 // num is nullable | 249 // num is nullable |
250 z = null; | 250 z = null; |
251 z = x; | 251 z = x; |
252 z = y; | 252 z = y; |
253 | 253 |
254 // bool is nullable | 254 // bool is nullable |
255 b = null; | 255 b = null; |
256 b = true; | 256 b = true; |
257 } | 257 } |
258 ''' | 258 ''' |
259 }, nonnullableTypes: <String>[ | 259 }, nonnullableTypes: <String>[ |
260 'int', | 260 'int', |
261 'double' | 261 'double' |
262 ]); | 262 ]); |
263 | 263 |
264 testChecker('Primitives and generics', { | 264 testChecker('Primitives and generics', { |
265 '/main.dart': ''' | 265 '/main.dart': ''' |
266 class A<T> { | 266 class A<T> { |
267 // TODO(vsm): This needs a static info indicating a runtime | 267 // TODO(vsm): This needs a static info indicating a runtime |
268 // check at construction. | 268 // check at construction. |
269 T x; | 269 T x; |
270 | 270 |
271 // TODO(vsm): Should this be a different type of DownCast? | 271 // TODO(vsm): Should this be a different type of DownCast? |
272 T foo() => /*warning:DownCastImplicit*/null; | 272 T foo() => /*info:DownCastImplicit*/null; |
273 | 273 |
274 void bar() { | 274 void bar() { |
275 int /*severe:InvalidVariableDeclaration*/x; | 275 int /*severe:InvalidVariableDeclaration*/x; |
276 num y; | 276 num y; |
277 // TODO(vsm): This should be a runtime check: | 277 // TODO(vsm): This should be a runtime check: |
278 // Transformed to: T z = cast(null, T) | 278 // Transformed to: T z = cast(null, T) |
279 T /*severe:InvalidVariableDeclaration*/z; | 279 T /*severe:InvalidVariableDeclaration*/z; |
280 } | 280 } |
281 | 281 |
282 void baz(T x, [T /*severe:InvalidVariableDeclaration*/y, T z = /*warni
ng:DownCastImplicit*/null]) { | 282 void baz(T x, [T /*severe:InvalidVariableDeclaration*/y, T z = /*info:
DownCastImplicit*/null]) { |
283 } | 283 } |
284 } | 284 } |
285 | 285 |
286 class B<T extends List> { | 286 class B<T extends List> { |
287 T x; | 287 T x; |
288 | 288 |
289 // T cannot be primitive. | 289 // T cannot be primitive. |
290 T foo() => null; | 290 T foo() => null; |
291 } | 291 } |
292 | 292 |
293 class C<T extends num> { | 293 class C<T extends num> { |
294 // TODO(vsm): This needs a static info indicating a runtime | 294 // TODO(vsm): This needs a static info indicating a runtime |
295 // check at construction. | 295 // check at construction. |
296 T x; | 296 T x; |
297 | 297 |
298 // TODO(vsm): Should this be a different type of DownCast? | 298 // TODO(vsm): Should this be a different type of DownCast? |
299 T foo() => /*warning:DownCastImplicit*/null; | 299 T foo() => /*info:DownCastImplicit*/null; |
300 } | 300 } |
301 ''' | 301 ''' |
302 }, nonnullableTypes: <String>[ | 302 }, nonnullableTypes: <String>[ |
303 'int', | 303 'int', |
304 'double' | 304 'double' |
305 ]); | 305 ]); |
306 | 306 |
307 testChecker('Constructors', { | 307 testChecker('Constructors', { |
308 '/main.dart': ''' | 308 '/main.dart': ''' |
309 const num z = 25; | 309 const num z = 25; |
310 Object obj = "world"; | 310 Object obj = "world"; |
311 | 311 |
312 class A { | 312 class A { |
313 int x; | 313 int x; |
314 String y; | 314 String y; |
315 | 315 |
316 A(this.x) : this.y = /*severe:StaticTypeError*/42; | 316 A(this.x) : this.y = /*severe:StaticTypeError*/42; |
317 | 317 |
318 A.c1(p): this.x = /*warning:DownCastImplicit*/z, this.y = /*info:Dynamic
Cast*/p; | 318 A.c1(p): this.x = /*info:DownCastImplicit*/z, this.y = /*info:DynamicCas
t*/p; |
319 | 319 |
320 A.c2(this.x, this.y); | 320 A.c2(this.x, this.y); |
321 | 321 |
322 A.c3(/*severe:InvalidParameterDeclaration*/num this.x, String this.y); | 322 A.c3(/*severe:InvalidParameterDeclaration*/num this.x, String this.y); |
323 } | 323 } |
324 | 324 |
325 class B extends A { | 325 class B extends A { |
326 B() : super(/*severe:StaticTypeError*/"hello"); | 326 B() : super(/*severe:StaticTypeError*/"hello"); |
327 | 327 |
328 B.c2(int x, String y) : super.c2(/*severe:StaticTypeError*/y, | 328 B.c2(int x, String y) : super.c2(/*severe:StaticTypeError*/y, |
329 /*severe:StaticTypeError*/x); | 329 /*severe:StaticTypeError*/x); |
330 | 330 |
331 B.c3(num x, Object y) : super.c3(x, /*warning:DownCastImplicit*/y); | 331 B.c3(num x, Object y) : super.c3(x, /*info:DownCastImplicit*/y); |
332 } | 332 } |
333 | 333 |
334 void main() { | 334 void main() { |
335 A a = new A.c2(/*warning:DownCastImplicit*/z, /*severe:StaticTypeError*
/z); | 335 A a = new A.c2(/*info:DownCastImplicit*/z, /*severe:StaticTypeError*/z)
; |
336 var b = new B.c2(/*severe:StaticTypeError*/"hello", /*warning:DownCastI
mplicit*/obj); | 336 var b = new B.c2(/*severe:StaticTypeError*/"hello", /*info:DownCastImpl
icit*/obj); |
337 } | 337 } |
338 ''' | 338 ''' |
339 }); | 339 }); |
340 | 340 |
341 testChecker('Unbound variable', { | 341 testChecker('Unbound variable', { |
342 '/main.dart': ''' | 342 '/main.dart': ''' |
343 void main() { | 343 void main() { |
344 dynamic y = /*pass should be severe:StaticTypeError*/unboundVariable; | 344 dynamic y = /*pass should be severe:StaticTypeError*/unboundVariable; |
345 } | 345 } |
346 ''' | 346 ''' |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 double d = 0.0; | 415 double d = 0.0; |
416 num n; | 416 num n; |
417 A a; | 417 A a; |
418 B b; | 418 B b; |
419 y = a; | 419 y = a; |
420 o = a; | 420 o = a; |
421 i = /*severe:StaticTypeError*/a; | 421 i = /*severe:StaticTypeError*/a; |
422 d = /*severe:StaticTypeError*/a; | 422 d = /*severe:StaticTypeError*/a; |
423 n = /*severe:StaticTypeError*/a; | 423 n = /*severe:StaticTypeError*/a; |
424 a = a; | 424 a = a; |
425 b = /*warning:DownCastImplicit*/a; | 425 b = /*info:DownCastImplicit*/a; |
426 } | 426 } |
427 ''' | 427 ''' |
428 }); | 428 }); |
429 | 429 |
430 testChecker('Ground type subtyping: assigning a subclass', { | 430 testChecker('Ground type subtyping: assigning a subclass', { |
431 '/main.dart': ''' | 431 '/main.dart': ''' |
432 | 432 |
433 class A {} | 433 class A {} |
434 class B extends A {} | 434 class B extends A {} |
435 class C extends A {} | 435 class C extends A {} |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
468 B left; | 468 B left; |
469 C right; | 469 C right; |
470 D bot; | 470 D bot; |
471 { | 471 { |
472 top = top; | 472 top = top; |
473 top = left; | 473 top = left; |
474 top = right; | 474 top = right; |
475 top = bot; | 475 top = bot; |
476 } | 476 } |
477 { | 477 { |
478 left = /*warning:DownCastImplicit*/top; | 478 left = /*info:DownCastImplicit*/top; |
479 left = left; | 479 left = left; |
480 left = /*severe:StaticTypeError*/right; | 480 left = /*severe:StaticTypeError*/right; |
481 left = bot; | 481 left = bot; |
482 } | 482 } |
483 { | 483 { |
484 right = /*warning:DownCastImplicit*/top; | 484 right = /*info:DownCastImplicit*/top; |
485 right = /*severe:StaticTypeError*/left; | 485 right = /*severe:StaticTypeError*/left; |
486 right = right; | 486 right = right; |
487 right = bot; | 487 right = bot; |
488 } | 488 } |
489 { | 489 { |
490 bot = /*warning:DownCastImplicit*/top; | 490 bot = /*info:DownCastImplicit*/top; |
491 bot = /*warning:DownCastImplicit*/left; | 491 bot = /*info:DownCastImplicit*/left; |
492 bot = /*warning:DownCastImplicit*/right; | 492 bot = /*info:DownCastImplicit*/right; |
493 bot = bot; | 493 bot = bot; |
494 } | 494 } |
495 } | 495 } |
496 ''' | 496 ''' |
497 }); | 497 }); |
498 | 498 |
499 testChecker('Function typing and subtyping: int and object', { | 499 testChecker('Function typing and subtyping: int and object', { |
500 '/main.dart': ''' | 500 '/main.dart': ''' |
501 | 501 |
502 typedef Object Top(int x); // Top of the lattice | 502 typedef Object Top(int x); // Top of the lattice |
503 typedef int Left(int x); // Left branch | 503 typedef int Left(int x); // Left branch |
504 typedef int Left2(int x); // Left branch | 504 typedef int Left2(int x); // Left branch |
505 typedef Object Right(Object x); // Right branch | 505 typedef Object Right(Object x); // Right branch |
506 typedef int Bot(Object x); // Bottom of the lattice | 506 typedef int Bot(Object x); // Bottom of the lattice |
507 | 507 |
508 Object top(int x) => x; | 508 Object top(int x) => x; |
509 int left(int x) => x; | 509 int left(int x) => x; |
510 Object right(Object x) => x; | 510 Object right(Object x) => x; |
511 int _bot(Object x) => /*warning:DownCastImplicit*/x; | 511 int _bot(Object x) => /*info:DownCastImplicit*/x; |
512 int bot(Object x) => x as int; | 512 int bot(Object x) => x as int; |
513 | 513 |
514 void main() { | 514 void main() { |
515 { // Check typedef equality | 515 { // Check typedef equality |
516 Left f = left; | 516 Left f = left; |
517 Left2 g = f; | 517 Left2 g = f; |
518 } | 518 } |
519 { | 519 { |
520 Top f; | 520 Top f; |
521 f = top; | 521 f = top; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
554 class A {} | 554 class A {} |
555 class B extends A {} | 555 class B extends A {} |
556 | 556 |
557 typedef A Top(B x); // Top of the lattice | 557 typedef A Top(B x); // Top of the lattice |
558 typedef B Left(B x); // Left branch | 558 typedef B Left(B x); // Left branch |
559 typedef B Left2(B x); // Left branch | 559 typedef B Left2(B x); // Left branch |
560 typedef A Right(A x); // Right branch | 560 typedef A Right(A x); // Right branch |
561 typedef B Bot(A x); // Bottom of the lattice | 561 typedef B Bot(A x); // Bottom of the lattice |
562 | 562 |
563 B left(B x) => x; | 563 B left(B x) => x; |
564 B _bot(A x) => /*warning:DownCastImplicit*/x; | 564 B _bot(A x) => /*info:DownCastImplicit*/x; |
565 B bot(A x) => x as B; | 565 B bot(A x) => x as B; |
566 A top(B x) => x; | 566 A top(B x) => x; |
567 A right(A x) => x; | 567 A right(A x) => x; |
568 | 568 |
569 void main() { | 569 void main() { |
570 { // Check typedef equality | 570 { // Check typedef equality |
571 Left f = left; | 571 Left f = left; |
572 Left2 g = f; | 572 Left2 g = f; |
573 } | 573 } |
574 { | 574 { |
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
991 f = n2n; | 991 f = n2n; |
992 f = /*warning:DownCastComposite*/i2i as Object; | 992 f = /*warning:DownCastComposite*/i2i as Object; |
993 f = /*warning:DownCastComposite*/n2n as Function; | 993 f = /*warning:DownCastComposite*/n2n as Function; |
994 } | 994 } |
995 { | 995 { |
996 A f; | 996 A f; |
997 f = new A(); | 997 f = new A(); |
998 f = /*severe:StaticTypeError*/new B(); | 998 f = /*severe:StaticTypeError*/new B(); |
999 f = /*severe:StaticTypeError*/i2i; | 999 f = /*severe:StaticTypeError*/i2i; |
1000 f = /*severe:StaticTypeError*/n2n; | 1000 f = /*severe:StaticTypeError*/n2n; |
1001 f = /*warning:DownCastImplicit*/i2i as Object; | 1001 f = /*info:DownCastImplicit*/i2i as Object; |
1002 f = /*warning:DownCastImplicit*/n2n as Function; | 1002 f = /*info:DownCastImplicit*/n2n as Function; |
1003 } | 1003 } |
1004 { | 1004 { |
1005 B f; | 1005 B f; |
1006 f = /*severe:StaticTypeError*/new A(); | 1006 f = /*severe:StaticTypeError*/new A(); |
1007 f = new B(); | 1007 f = new B(); |
1008 f = /*severe:StaticTypeError*/i2i; | 1008 f = /*severe:StaticTypeError*/i2i; |
1009 f = /*severe:StaticTypeError*/n2n; | 1009 f = /*severe:StaticTypeError*/n2n; |
1010 f = /*warning:DownCastImplicit*/i2i as Object; | 1010 f = /*info:DownCastImplicit*/i2i as Object; |
1011 f = /*warning:DownCastImplicit*/n2n as Function; | 1011 f = /*info:DownCastImplicit*/n2n as Function; |
1012 } | 1012 } |
1013 { | 1013 { |
1014 Function f; | 1014 Function f; |
1015 f = new A(); | 1015 f = new A(); |
1016 f = new B(); | 1016 f = new B(); |
1017 f = i2i; | 1017 f = i2i; |
1018 f = n2n; | 1018 f = n2n; |
1019 f = /*warning:DownCastImplicit*/i2i as Object; | 1019 f = /*info:DownCastImplicit*/i2i as Object; |
1020 f = (n2n as Function); | 1020 f = (n2n as Function); |
1021 } | 1021 } |
1022 } | 1022 } |
1023 ''' | 1023 ''' |
1024 }); | 1024 }); |
1025 | 1025 |
1026 testChecker('Function typing and subtyping: void', { | 1026 testChecker('Function typing and subtyping: void', { |
1027 '/main.dart': ''' | 1027 '/main.dart': ''' |
1028 | 1028 |
1029 class A { | 1029 class A { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1129 | 1129 |
1130 // M<T> <: M<S> iff T :< S | 1130 // M<T> <: M<S> iff T :< S |
1131 mOfCs = /*warning:DownCastComposite*/mOfAs; | 1131 mOfCs = /*warning:DownCastComposite*/mOfAs; |
1132 mOfCs = /*severe:StaticTypeError*/mOfBs; | 1132 mOfCs = /*severe:StaticTypeError*/mOfBs; |
1133 mOfCs = mOfCs; | 1133 mOfCs = mOfCs; |
1134 | 1134 |
1135 // N </: L<C> | 1135 // N </: L<C> |
1136 mOfCs = /*severe:StaticTypeError*/ns; | 1136 mOfCs = /*severe:StaticTypeError*/ns; |
1137 | 1137 |
1138 // Concrete subclass subtyping | 1138 // Concrete subclass subtyping |
1139 ns = /*warning:DownCastImplicit*/lOfAs; | 1139 ns = /*info:DownCastImplicit*/lOfAs; |
1140 ns = /*severe:StaticTypeError*/lOfBs; | 1140 ns = /*severe:StaticTypeError*/lOfBs; |
1141 ns = /*severe:StaticTypeError*/lOfCs; | 1141 ns = /*severe:StaticTypeError*/lOfCs; |
1142 ns = /*warning:DownCastImplicit*/mOfAs; | 1142 ns = /*info:DownCastImplicit*/mOfAs; |
1143 ns = /*severe:StaticTypeError*/mOfBs; | 1143 ns = /*severe:StaticTypeError*/mOfBs; |
1144 ns = /*severe:StaticTypeError*/mOfCs; | 1144 ns = /*severe:StaticTypeError*/mOfCs; |
1145 ns = ns; | 1145 ns = ns; |
1146 } | 1146 } |
1147 ''' | 1147 ''' |
1148 }, | 1148 }, |
1149 relaxedCasts: false); | 1149 relaxedCasts: false); |
1150 | 1150 |
1151 testChecker( | 1151 testChecker( |
1152 'Relaxed casts', | 1152 'Relaxed casts', |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1196 lOfAs = /*severe:StaticTypeError*/mOfOs; | 1196 lOfAs = /*severe:StaticTypeError*/mOfOs; |
1197 lOfAs = mOfAs; | 1197 lOfAs = mOfAs; |
1198 lOfAs = /*warning:DownCastComposite*/lOfDs; | 1198 lOfAs = /*warning:DownCastComposite*/lOfDs; |
1199 lOfAs = /*warning:DownCastComposite*/lOfOs; | 1199 lOfAs = /*warning:DownCastComposite*/lOfOs; |
1200 lOfAs = lOfAs; | 1200 lOfAs = lOfAs; |
1201 } | 1201 } |
1202 { | 1202 { |
1203 mOfDs = mOfDs; | 1203 mOfDs = mOfDs; |
1204 mOfDs = mOfOs; | 1204 mOfDs = mOfOs; |
1205 mOfDs = mOfAs; | 1205 mOfDs = mOfAs; |
1206 mOfDs = /*warning:DownCastImplicit*/lOfDs; | 1206 mOfDs = /*info:DownCastImplicit*/lOfDs; |
1207 mOfDs = /*warning:DownCastImplicit*/lOfOs; | 1207 mOfDs = /*info:DownCastImplicit*/lOfOs; |
1208 mOfDs = /*warning:DownCastImplicit*/lOfAs; | 1208 mOfDs = /*info:DownCastImplicit*/lOfAs; |
1209 } | 1209 } |
1210 { | 1210 { |
1211 mOfOs = mOfDs; | 1211 mOfOs = mOfDs; |
1212 mOfOs = mOfOs; | 1212 mOfOs = mOfOs; |
1213 mOfOs = mOfAs; | 1213 mOfOs = mOfAs; |
1214 mOfOs = /*warning:DownCastImplicit*/lOfDs; | 1214 mOfOs = /*info:DownCastImplicit*/lOfDs; |
1215 mOfOs = /*warning:DownCastImplicit*/lOfOs; | 1215 mOfOs = /*info:DownCastImplicit*/lOfOs; |
1216 mOfOs = /*severe:StaticTypeError*/lOfAs; | 1216 mOfOs = /*severe:StaticTypeError*/lOfAs; |
1217 } | 1217 } |
1218 { | 1218 { |
1219 mOfAs = /*warning:DownCastComposite*/mOfDs; | 1219 mOfAs = /*warning:DownCastComposite*/mOfDs; |
1220 mOfAs = /*warning:DownCastComposite*/mOfOs; | 1220 mOfAs = /*warning:DownCastComposite*/mOfOs; |
1221 mOfAs = mOfAs; | 1221 mOfAs = mOfAs; |
1222 mOfAs = /*warning:DownCastComposite*/lOfDs; | 1222 mOfAs = /*warning:DownCastComposite*/lOfDs; |
1223 mOfAs = /*warning:DownCastComposite*/lOfOs; | 1223 mOfAs = /*warning:DownCastComposite*/lOfOs; |
1224 mOfAs = /*warning:DownCastComposite*/lOfAs; | 1224 mOfAs = /*warning:DownCastComposite*/lOfAs; |
1225 } | 1225 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1258 | 1258 |
1259 testChecker('Type checking literals', { | 1259 testChecker('Type checking literals', { |
1260 '/main.dart': ''' | 1260 '/main.dart': ''' |
1261 test() { | 1261 test() { |
1262 num n = 3; | 1262 num n = 3; |
1263 int i = 3; | 1263 int i = 3; |
1264 String s = "hello"; | 1264 String s = "hello"; |
1265 { | 1265 { |
1266 List<int> l = <int>[i]; | 1266 List<int> l = <int>[i]; |
1267 l = <int>[/*severe:StaticTypeError*/s]; | 1267 l = <int>[/*severe:StaticTypeError*/s]; |
1268 l = <int>[/*warning:DownCastImplicit*/n]; | 1268 l = <int>[/*info:DownCastImplicit*/n]; |
1269 l = <int>[i, /*warning:DownCastImplicit*/n, /*severe:StaticTypeEr
ror*/s]; | 1269 l = <int>[i, /*info:DownCastImplicit*/n, /*severe:StaticTypeError
*/s]; |
1270 } | 1270 } |
1271 { | 1271 { |
1272 List l = [i]; | 1272 List l = [i]; |
1273 l = [s]; | 1273 l = [s]; |
1274 l = [n]; | 1274 l = [n]; |
1275 l = [i, n, s]; | 1275 l = [i, n, s]; |
1276 } | 1276 } |
1277 { | 1277 { |
1278 Map<String, int> m = <String, int>{s: i}; | 1278 Map<String, int> m = <String, int>{s: i}; |
1279 m = <String, int>{s: /*severe:StaticTypeError*/s}; | 1279 m = <String, int>{s: /*severe:StaticTypeError*/s}; |
1280 m = <String, int>{s: /*warning:DownCastImplicit*/n}; | 1280 m = <String, int>{s: /*info:DownCastImplicit*/n}; |
1281 m = <String, int>{s: i, | 1281 m = <String, int>{s: i, |
1282 s: /*warning:DownCastImplicit*/n, | 1282 s: /*info:DownCastImplicit*/n, |
1283 s: /*severe:StaticTypeError*/s}; | 1283 s: /*severe:StaticTypeError*/s}; |
1284 } | 1284 } |
1285 // TODO(leafp): We can't currently test for key errors since the | 1285 // TODO(leafp): We can't currently test for key errors since the |
1286 // error marker binds to the entire entry. | 1286 // error marker binds to the entire entry. |
1287 { | 1287 { |
1288 Map m = {s: i}; | 1288 Map m = {s: i}; |
1289 m = {s: s}; | 1289 m = {s: s}; |
1290 m = {s: n}; | 1290 m = {s: n}; |
1291 m = {s: i, | 1291 m = {s: i, |
1292 s: n, | 1292 s: n, |
1293 s: s}; | 1293 s: s}; |
1294 m = {i: s, | 1294 m = {i: s, |
1295 n: s, | 1295 n: s, |
1296 s: s}; | 1296 s: s}; |
1297 } | 1297 } |
1298 } | 1298 } |
1299 ''' | 1299 ''' |
1300 }); | 1300 }); |
1301 | 1301 |
1302 testChecker('casts in constant contexts', { | 1302 testChecker('casts in constant contexts', { |
1303 '/main.dart': ''' | 1303 '/main.dart': ''' |
1304 class A { | 1304 class A { |
1305 static const num n = 3.0; | 1305 static const num n = 3.0; |
1306 static const int i = /*info:AssignmentCast*/n; | 1306 static const int i = /*info:AssignmentCast*/n; |
1307 final int fi; | 1307 final int fi; |
1308 const A(num a) : this.fi = /*warning:DownCastImplicit*/a; | 1308 const A(num a) : this.fi = /*info:DownCastImplicit*/a; |
1309 } | 1309 } |
1310 class B extends A { | 1310 class B extends A { |
1311 const B(Object a) : super(/*warning:DownCastImplicit*/a); | 1311 const B(Object a) : super(/*info:DownCastImplicit*/a); |
1312 } | 1312 } |
1313 void foo(Object o) { | 1313 void foo(Object o) { |
1314 var a = const A(/*warning:DownCastImplicit*/o); | 1314 var a = const A(/*info:DownCastImplicit*/o); |
1315 } | 1315 } |
1316 ''' | 1316 ''' |
1317 }); | 1317 }); |
1318 | 1318 |
1319 testChecker('casts in conditionals', { | 1319 testChecker('casts in conditionals', { |
1320 '/main.dart': ''' | 1320 '/main.dart': ''' |
1321 main() { | 1321 main() { |
1322 bool b = true; | 1322 bool b = true; |
1323 num x = b ? 1 : 2.3; | 1323 num x = b ? 1 : 2.3; |
1324 int y = /*info:AssignmentCast*/b ? 1 : 2.3; | 1324 int y = /*info:AssignmentCast*/b ? 1 : 2.3; |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1689 (/*severe:StaticTypeError*/x += 3.14); | 1689 (/*severe:StaticTypeError*/x += 3.14); |
1690 | 1690 |
1691 double y = 0.0; | 1691 double y = 0.0; |
1692 y += 5; | 1692 y += 5; |
1693 y += 3.14; | 1693 y += 3.14; |
1694 | 1694 |
1695 num z = 0; | 1695 num z = 0; |
1696 z += 5; | 1696 z += 5; |
1697 z += 3.14; | 1697 z += 3.14; |
1698 | 1698 |
1699 x = /*warning:DownCastImplicit*/x + z; | 1699 x = /*info:DownCastImplicit*/x + z; |
1700 x += /*warning:DownCastImplicit*/z; | 1700 x += /*info:DownCastImplicit*/z; |
1701 y = /*warning:DownCastImplicit*/y + z; | 1701 y = /*info:DownCastImplicit*/y + z; |
1702 y += /*warning:DownCastImplicit*/z; | 1702 y += /*info:DownCastImplicit*/z; |
1703 | 1703 |
1704 dynamic w = 42; | 1704 dynamic w = 42; |
1705 x += /*info:DynamicCast*/w; | 1705 x += /*info:DynamicCast*/w; |
1706 y += /*info:DynamicCast*/w; | 1706 y += /*info:DynamicCast*/w; |
1707 z += /*info:DynamicCast*/w; | 1707 z += /*info:DynamicCast*/w; |
1708 | 1708 |
1709 A a = new A(); | 1709 A a = new A(); |
1710 B b = new B(); | 1710 B b = new B(); |
1711 var c = foo(); | 1711 var c = foo(); |
1712 a = a * b; | 1712 a = a * b; |
(...skipping 933 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2646 num myMax(num x, num y) => max(x, y); | 2646 num myMax(num x, num y) => max(x, y); |
2647 | 2647 |
2648 main() { | 2648 main() { |
2649 // Okay if static types match. | 2649 // Okay if static types match. |
2650 printInt(max(1, 2)); | 2650 printInt(max(1, 2)); |
2651 printInt(min(1, 2)); | 2651 printInt(min(1, 2)); |
2652 printDouble(max(1.0, 2.0)); | 2652 printDouble(max(1.0, 2.0)); |
2653 printDouble(min(1.0, 2.0)); | 2653 printDouble(min(1.0, 2.0)); |
2654 | 2654 |
2655 // No help for user-defined functions from num->num->num. | 2655 // No help for user-defined functions from num->num->num. |
2656 printInt(/*warning:DownCastImplicit*/myMax(1, 2)); | 2656 printInt(/*info:DownCastImplicit*/myMax(1, 2)); |
2657 printInt(myMax(1, 2) as int); | 2657 printInt(myMax(1, 2) as int); |
2658 | 2658 |
2659 // Mixing int and double means return type is num. | 2659 // Mixing int and double means return type is num. |
2660 printInt(/*warning:DownCastImplicit*/max(1, 2.0)); | 2660 printInt(/*info:DownCastImplicit*/max(1, 2.0)); |
2661 printInt(/*warning:DownCastImplicit*/min(1, 2.0)); | 2661 printInt(/*info:DownCastImplicit*/min(1, 2.0)); |
2662 printDouble(/*warning:DownCastImplicit*/max(1, 2.0)); | 2662 printDouble(/*info:DownCastImplicit*/max(1, 2.0)); |
2663 printDouble(/*warning:DownCastImplicit*/min(1, 2.0)); | 2663 printDouble(/*info:DownCastImplicit*/min(1, 2.0)); |
2664 | 2664 |
2665 // Types other than int and double are not accepted. | 2665 // Types other than int and double are not accepted. |
2666 printInt( | 2666 printInt( |
2667 /*warning:DownCastImplicit*/min( | 2667 /*info:DownCastImplicit*/min( |
2668 /*severe:StaticTypeError*/"hi", | 2668 /*severe:StaticTypeError*/"hi", |
2669 /*severe:StaticTypeError*/"there")); | 2669 /*severe:StaticTypeError*/"there")); |
2670 } | 2670 } |
2671 ''' | 2671 ''' |
2672 }); | 2672 }); |
2673 }); | 2673 }); |
2674 } | 2674 } |
OLD | NEW |