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