Chromium Code Reviews| 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 // TODO(jmesserly): this file needs to be refactored, it's a port from | 5 // TODO(jmesserly): this file needs to be refactored, it's a port from |
| 6 // package:dev_compiler's tests | 6 // package:dev_compiler's tests |
| 7 /// General type checking tests | 7 /// General type checking tests |
| 8 library analyzer.test.src.task.strong.checker_test; | 8 library analyzer.test.src.task.strong.checker_test; |
| 9 | 9 |
| 10 import 'package:unittest/unittest.dart'; | 10 import 'package:unittest/unittest.dart'; |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 276 testChecker('Void subtyping', { | 276 testChecker('Void subtyping', { |
| 277 '/main.dart': ''' | 277 '/main.dart': ''' |
| 278 typedef int Foo(); | 278 typedef int Foo(); |
| 279 void foo() {} | 279 void foo() {} |
| 280 void main () { | 280 void main () { |
| 281 Foo x = /*severe:STATIC_TYPE_ERROR*/foo(); | 281 Foo x = /*severe:STATIC_TYPE_ERROR*/foo(); |
| 282 } | 282 } |
| 283 ''' | 283 ''' |
| 284 }); | 284 }); |
| 285 | 285 |
| 286 testChecker('Ground type subtyping: dynamic is top', { | 286 group('Ground type subtyping:', () { |
| 287 '/main.dart': ''' | 287 testChecker('dynamic is top', { |
| 288 '/main.dart': ''' | |
| 288 | 289 |
| 289 class A {} | 290 class A {} |
| 290 class B extends A {} | 291 class B extends A {} |
| 291 | 292 |
| 292 void main() { | 293 void main() { |
| 293 dynamic y; | 294 dynamic y; |
| 294 Object o; | 295 Object o; |
| 295 int i = 0; | 296 int i = 0; |
| 296 double d = 0.0; | 297 double d = 0.0; |
| 297 num n; | 298 num n; |
| 298 A a; | 299 A a; |
| 299 B b; | 300 B b; |
| 300 y = o; | 301 y = o; |
| 301 y = i; | 302 y = i; |
| 302 y = d; | 303 y = d; |
| 303 y = n; | 304 y = n; |
| 304 y = a; | 305 y = a; |
| 305 y = b; | 306 y = b; |
| 306 } | 307 } |
| 307 ''' | 308 ''' |
| 308 }); | 309 }); |
| 309 | 310 |
| 310 testChecker('Ground type subtyping: dynamic downcasts', { | 311 testChecker('dynamic downcasts', { |
| 311 '/main.dart': ''' | 312 '/main.dart': ''' |
| 312 | 313 |
| 313 class A {} | 314 class A {} |
| 314 class B extends A {} | 315 class B extends A {} |
| 315 | 316 |
| 316 void main() { | 317 void main() { |
| 317 dynamic y; | 318 dynamic y; |
| 318 Object o; | 319 Object o; |
| 319 int i = 0; | 320 int i = 0; |
| 320 double d = 0.0; | 321 double d = 0.0; |
| 321 num n; | 322 num n; |
| 322 A a; | 323 A a; |
| 323 B b; | 324 B b; |
| 324 o = y; | 325 o = y; |
| 325 i = /*info:DYNAMIC_CAST*/y; | 326 i = /*info:DYNAMIC_CAST*/y; |
| 326 d = /*info:DYNAMIC_CAST*/y; | 327 d = /*info:DYNAMIC_CAST*/y; |
| 327 n = /*info:DYNAMIC_CAST*/y; | 328 n = /*info:DYNAMIC_CAST*/y; |
| 328 a = /*info:DYNAMIC_CAST*/y; | 329 a = /*info:DYNAMIC_CAST*/y; |
| 329 b = /*info:DYNAMIC_CAST*/y; | 330 b = /*info:DYNAMIC_CAST*/y; |
| 330 } | 331 } |
| 331 ''' | 332 ''' |
| 332 }); | 333 }); |
| 333 | 334 |
| 334 testChecker('Ground type subtyping: assigning a class', { | 335 testChecker('assigning a class', { |
| 335 '/main.dart': ''' | 336 '/main.dart': ''' |
| 336 | 337 |
| 337 class A {} | 338 class A {} |
| 338 class B extends A {} | 339 class B extends A {} |
| 339 | 340 |
| 340 void main() { | 341 void main() { |
| 341 dynamic y; | 342 dynamic y; |
| 342 Object o; | 343 Object o; |
| 343 int i = 0; | 344 int i = 0; |
| 344 double d = 0.0; | 345 double d = 0.0; |
| 345 num n; | 346 num n; |
| 346 A a; | 347 A a; |
| 347 B b; | 348 B b; |
| 348 y = a; | 349 y = a; |
| 349 o = a; | 350 o = a; |
| 350 i = /*severe:STATIC_TYPE_ERROR*/a; | 351 i = /*severe:STATIC_TYPE_ERROR*/a; |
| 351 d = /*severe:STATIC_TYPE_ERROR*/a; | 352 d = /*severe:STATIC_TYPE_ERROR*/a; |
| 352 n = /*severe:STATIC_TYPE_ERROR*/a; | 353 n = /*severe:STATIC_TYPE_ERROR*/a; |
| 353 a = a; | 354 a = a; |
| 354 b = /*info:DOWN_CAST_IMPLICIT*/a; | 355 b = /*info:DOWN_CAST_IMPLICIT*/a; |
| 355 } | 356 } |
| 356 ''' | 357 ''' |
| 357 }); | 358 }); |
| 358 | 359 |
| 359 testChecker('Ground type subtyping: assigning a subclass', { | 360 testChecker('assigning a subclass', { |
| 360 '/main.dart': ''' | 361 '/main.dart': ''' |
| 361 | 362 |
| 362 class A {} | 363 class A {} |
| 363 class B extends A {} | 364 class B extends A {} |
| 364 class C extends A {} | 365 class C extends A {} |
| 365 | 366 |
| 366 void main() { | 367 void main() { |
| 367 dynamic y; | 368 dynamic y; |
| 368 Object o; | 369 Object o; |
| 369 int i = 0; | 370 int i = 0; |
| 370 double d = 0.0; | 371 double d = 0.0; |
| 371 num n; | 372 num n; |
| 372 A a; | 373 A a; |
| 373 B b; | 374 B b; |
| 374 C c; | 375 C c; |
| 375 y = b; | 376 y = b; |
| 376 o = b; | 377 o = b; |
| 377 i = /*severe:STATIC_TYPE_ERROR*/b; | 378 i = /*severe:STATIC_TYPE_ERROR*/b; |
| 378 d = /*severe:STATIC_TYPE_ERROR*/b; | 379 d = /*severe:STATIC_TYPE_ERROR*/b; |
| 379 n = /*severe:STATIC_TYPE_ERROR*/b; | 380 n = /*severe:STATIC_TYPE_ERROR*/b; |
| 380 a = b; | 381 a = b; |
| 381 b = b; | 382 b = b; |
| 382 c = /*severe:STATIC_TYPE_ERROR*/b; | 383 c = /*severe:STATIC_TYPE_ERROR*/b; |
| 383 } | 384 } |
| 384 ''' | 385 ''' |
| 385 }); | 386 }); |
| 386 | 387 |
| 387 testChecker('Ground type subtyping: interfaces', { | 388 testChecker('interfaces', { |
| 388 '/main.dart': ''' | 389 '/main.dart': ''' |
| 389 | 390 |
| 390 class A {} | 391 class A {} |
| 391 class B extends A {} | 392 class B extends A {} |
| 392 class C extends A {} | 393 class C extends A {} |
| 393 class D extends B implements C {} | 394 class D extends B implements C {} |
| 394 | 395 |
| 395 void main() { | 396 void main() { |
| 396 A top; | 397 A top; |
| 397 B left; | 398 B left; |
| 398 C right; | 399 C right; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 416 right = bot; | 417 right = bot; |
| 417 } | 418 } |
| 418 { | 419 { |
| 419 bot = /*info:DOWN_CAST_IMPLICIT*/top; | 420 bot = /*info:DOWN_CAST_IMPLICIT*/top; |
| 420 bot = /*info:DOWN_CAST_IMPLICIT*/left; | 421 bot = /*info:DOWN_CAST_IMPLICIT*/left; |
| 421 bot = /*info:DOWN_CAST_IMPLICIT*/right; | 422 bot = /*info:DOWN_CAST_IMPLICIT*/right; |
| 422 bot = bot; | 423 bot = bot; |
| 423 } | 424 } |
| 424 } | 425 } |
| 425 ''' | 426 ''' |
| 427 }); | |
| 426 }); | 428 }); |
| 427 | 429 |
| 428 testChecker('Function typing and subtyping: int and object', { | 430 group('Function typing and subtyping:', () { |
| 429 '/main.dart': ''' | 431 testChecker('int and object', { |
| 432 '/main.dart': ''' | |
| 430 | 433 |
| 431 typedef Object Top(int x); // Top of the lattice | 434 typedef Object Top(int x); // Top of the lattice |
| 432 typedef int Left(int x); // Left branch | 435 typedef int Left(int x); // Left branch |
| 433 typedef int Left2(int x); // Left branch | 436 typedef int Left2(int x); // Left branch |
| 434 typedef Object Right(Object x); // Right branch | 437 typedef Object Right(Object x); // Right branch |
| 435 typedef int Bot(Object x); // Bottom of the lattice | 438 typedef int Bot(Object x); // Bottom of the lattice |
| 436 | 439 |
| 437 Object top(int x) => x; | 440 Object globalTop(int x) => x; |
| 438 int left(int x) => x; | 441 int globalLeft(int x) => x; |
| 439 Object right(Object x) => x; | 442 Object globalRight(Object x) => x; |
| 440 int _bot(Object x) => /*info:DOWN_CAST_IMPLICIT*/x; | 443 int _bot(Object x) => /*info:DOWN_CAST_IMPLICIT*/x; |
| 441 int bot(Object x) => x as int; | 444 int globalBot(Object x) => x as int; |
| 442 | 445 |
| 443 void main() { | 446 void main() { |
| 447 // Note: use locals so we only know the type, not that it's a specific | |
| 448 // function declaration. (we can issue better errors in that case.) | |
| 449 var top = globalTop; | |
| 450 var left = globalLeft; | |
| 451 var right = globalRight; | |
| 452 var bot = globalBot; | |
|
vsm
2016/02/03 23:52:00
Perhaps a test to cover the static method case (er
Jennifer Messerly
2016/02/04 00:41:30
instance methods are covered by this test (line 16
| |
| 453 | |
| 444 { // Check typedef equality | 454 { // Check typedef equality |
| 445 Left f = left; | 455 Left f = left; |
| 446 Left2 g = f; | 456 Left2 g = f; |
| 447 } | 457 } |
| 448 { | 458 { |
| 449 Top f; | 459 Top f; |
| 450 f = top; | 460 f = top; |
| 451 f = left; | 461 f = left; |
| 452 f = right; | 462 f = right; |
| 453 f = bot; | 463 f = bot; |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 468 } | 478 } |
| 469 { | 479 { |
| 470 Bot f; | 480 Bot f; |
| 471 f = /*warning:DOWN_CAST_COMPOSITE*/top; | 481 f = /*warning:DOWN_CAST_COMPOSITE*/top; |
| 472 f = /*warning:DOWN_CAST_COMPOSITE*/left; | 482 f = /*warning:DOWN_CAST_COMPOSITE*/left; |
| 473 f = /*warning:DOWN_CAST_COMPOSITE*/right; | 483 f = /*warning:DOWN_CAST_COMPOSITE*/right; |
| 474 f = bot; | 484 f = bot; |
| 475 } | 485 } |
| 476 } | 486 } |
| 477 ''' | 487 ''' |
| 478 }); | 488 }); |
| 479 | 489 |
| 480 testChecker('Function typing and subtyping: classes', { | 490 testChecker('classes', { |
| 481 '/main.dart': ''' | 491 '/main.dart': ''' |
| 482 | 492 |
| 483 class A {} | 493 class A {} |
| 484 class B extends A {} | 494 class B extends A {} |
| 485 | 495 |
| 486 typedef A Top(B x); // Top of the lattice | 496 typedef A Top(B x); // Top of the lattice |
| 487 typedef B Left(B x); // Left branch | 497 typedef B Left(B x); // Left branch |
| 488 typedef B Left2(B x); // Left branch | 498 typedef B Left2(B x); // Left branch |
| 489 typedef A Right(A x); // Right branch | 499 typedef A Right(A x); // Right branch |
| 490 typedef B Bot(A x); // Bottom of the lattice | 500 typedef B Bot(A x); // Bottom of the lattice |
| 491 | 501 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 502 } | 512 } |
| 503 { | 513 { |
| 504 Top f; | 514 Top f; |
| 505 f = top; | 515 f = top; |
| 506 f = left; | 516 f = left; |
| 507 f = right; | 517 f = right; |
| 508 f = bot; | 518 f = bot; |
| 509 } | 519 } |
| 510 { | 520 { |
| 511 Left f; | 521 Left f; |
| 512 f = /*warning:DOWN_CAST_COMPOSITE*/top; | 522 f = /*severe:STATIC_TYPE_ERROR*/top; |
|
vsm
2016/02/03 23:52:00
nice!
| |
| 513 f = left; | 523 f = left; |
| 514 f = /*warning:DOWN_CAST_COMPOSITE*/right; // Should we reject this? | 524 f = /*severe:STATIC_TYPE_ERROR*/right; |
| 515 f = bot; | 525 f = bot; |
| 516 } | 526 } |
| 517 { | 527 { |
| 518 Right f; | 528 Right f; |
| 519 f = /*warning:DOWN_CAST_COMPOSITE*/top; | 529 f = /*severe:STATIC_TYPE_ERROR*/top; |
| 520 f = /*warning:DOWN_CAST_COMPOSITE*/left; // Should we reject this? | 530 f = /*severe:STATIC_TYPE_ERROR*/left; |
| 521 f = right; | 531 f = right; |
| 522 f = bot; | 532 f = bot; |
| 523 } | 533 } |
| 524 { | 534 { |
| 525 Bot f; | 535 Bot f; |
| 526 f = /*warning:DOWN_CAST_COMPOSITE*/top; | 536 f = /*severe:STATIC_TYPE_ERROR*/top; |
| 527 f = /*warning:DOWN_CAST_COMPOSITE*/left; | 537 f = /*severe:STATIC_TYPE_ERROR*/left; |
| 528 f = /*warning:DOWN_CAST_COMPOSITE*/right; | 538 f = /*severe:STATIC_TYPE_ERROR*/right; |
| 529 f = bot; | 539 f = bot; |
| 530 } | 540 } |
| 531 } | 541 } |
| 532 ''' | 542 ''' |
| 533 }); | 543 }); |
| 534 | 544 |
| 535 testChecker('Function typing and subtyping: dynamic', { | 545 testChecker('dynamic', { |
| 536 '/main.dart': ''' | 546 '/main.dart': ''' |
| 537 | 547 |
| 538 class A {} | 548 class A {} |
| 539 | 549 |
| 540 typedef dynamic Top(dynamic x); // Top of the lattice | 550 typedef dynamic Top(dynamic x); // Top of the lattice |
| 541 typedef dynamic Left(A x); // Left branch | 551 typedef dynamic Left(A x); // Left branch |
| 542 typedef A Right(dynamic x); // Right branch | 552 typedef A Right(dynamic x); // Right branch |
| 543 typedef A Bottom(A x); // Bottom of the lattice | 553 typedef A Bottom(A x); // Bottom of the lattice |
| 544 | 554 |
| 545 dynamic left(A x) => x; | 555 dynamic left(A x) => x; |
| 546 A bot(A x) => x; | 556 A bot(A x) => x; |
| 547 dynamic top(dynamic x) => x; | 557 dynamic top(dynamic x) => x; |
| 548 A right(dynamic x) => /*info:DYNAMIC_CAST*/x; | 558 A right(dynamic x) => /*info:DYNAMIC_CAST*/x; |
| 549 | 559 |
| 550 void main() { | 560 void main() { |
| 551 { | 561 { |
| 552 Top f; | 562 Top f; |
| 553 f = top; | 563 f = top; |
| 554 f = left; | 564 f = left; |
| 555 f = right; | 565 f = right; |
| 556 f = bot; | 566 f = bot; |
| 557 } | 567 } |
| 558 { | 568 { |
| 559 Left f; | 569 Left f; |
| 560 f = /*warning:DOWN_CAST_COMPOSITE*/top; | 570 f = /*severe:STATIC_TYPE_ERROR*/top; |
| 561 f = left; | 571 f = left; |
| 562 f = /*warning:DOWN_CAST_COMPOSITE*/right; | 572 f = /*severe:STATIC_TYPE_ERROR*/right; |
| 563 f = bot; | 573 f = bot; |
| 564 } | 574 } |
| 565 { | 575 { |
| 566 Right f; | 576 Right f; |
| 567 f = /*warning:DOWN_CAST_COMPOSITE*/top; | 577 f = /*severe:STATIC_TYPE_ERROR*/top; |
| 568 f = /*warning:DOWN_CAST_COMPOSITE*/left; | 578 f = /*severe:STATIC_TYPE_ERROR*/left; |
| 569 f = right; | 579 f = right; |
| 570 f = bot; | 580 f = bot; |
| 571 } | 581 } |
| 572 { | 582 { |
| 573 Bottom f; | 583 Bottom f; |
| 574 f = /*warning:DOWN_CAST_COMPOSITE*/top; | 584 f = /*severe:STATIC_TYPE_ERROR*/top; |
| 575 f = /*warning:DOWN_CAST_COMPOSITE*/left; | 585 f = /*severe:STATIC_TYPE_ERROR*/left; |
| 576 f = /*warning:DOWN_CAST_COMPOSITE*/right; | 586 f = /*severe:STATIC_TYPE_ERROR*/right; |
| 577 f = bot; | 587 f = bot; |
| 578 } | 588 } |
| 579 } | 589 } |
| 580 ''' | 590 ''' |
| 581 }); | 591 }); |
| 582 | 592 |
| 583 testChecker('Function typing and subtyping: function literal variance', { | 593 testChecker('function literal variance', { |
| 584 '/main.dart': ''' | 594 '/main.dart': ''' |
| 585 | 595 |
| 586 class A {} | 596 class A {} |
| 587 class B extends A {} | 597 class B extends A {} |
| 588 | 598 |
| 589 typedef T Function2<S, T>(S z); | 599 typedef T Function2<S, T>(S z); |
| 590 | 600 |
| 591 A top(B x) => x; | 601 A top(B x) => x; |
| 592 B left(B x) => x; | 602 B left(B x) => x; |
| 593 A right(A x) => x; | 603 A right(A x) => x; |
| 594 B bot(A x) => x as B; | 604 B bot(A x) => x as B; |
| 595 | 605 |
| 596 void main() { | 606 void main() { |
| 597 { | 607 { |
| 598 Function2<B, A> f; | 608 Function2<B, A> f; |
| 599 f = top; | 609 f = top; |
| 600 f = left; | 610 f = left; |
| 601 f = right; | 611 f = right; |
| 602 f = bot; | 612 f = bot; |
| 603 } | 613 } |
| 604 { | 614 { |
| 605 Function2<B, B> f; | 615 Function2<B, B> f; |
| 606 f = /*warning:DOWN_CAST_COMPOSITE*/top; | 616 f = /*severe:STATIC_TYPE_ERROR*/top; |
| 607 f = left; | 617 f = left; |
| 608 f = /*warning:DOWN_CAST_COMPOSITE*/right; // Should we reject this? | 618 f = /*severe:STATIC_TYPE_ERROR*/right; |
| 609 f = bot; | 619 f = bot; |
| 610 } | 620 } |
| 611 { | 621 { |
| 612 Function2<A, A> f; | 622 Function2<A, A> f; |
| 613 f = /*warning:DOWN_CAST_COMPOSITE*/top; | 623 f = /*severe:STATIC_TYPE_ERROR*/top; |
| 614 f = /*warning:DOWN_CAST_COMPOSITE*/left; // Should we reject this? | 624 f = /*severe:STATIC_TYPE_ERROR*/left; |
| 615 f = right; | 625 f = right; |
| 616 f = bot; | 626 f = bot; |
| 617 } | 627 } |
| 618 { | 628 { |
| 619 Function2<A, B> f; | 629 Function2<A, B> f; |
| 620 f = /*warning:DOWN_CAST_COMPOSITE*/top; | 630 f = /*severe:STATIC_TYPE_ERROR*/top; |
| 621 f = /*warning:DOWN_CAST_COMPOSITE*/left; | 631 f = /*severe:STATIC_TYPE_ERROR*/left; |
| 622 f = /*warning:DOWN_CAST_COMPOSITE*/right; | 632 f = /*severe:STATIC_TYPE_ERROR*/right; |
| 623 f = bot; | 633 f = bot; |
| 624 } | 634 } |
| 625 } | 635 } |
| 626 ''' | 636 ''' |
| 627 }); | 637 }); |
| 628 | 638 |
| 629 testChecker('Function typing and subtyping: function variable variance', { | 639 testChecker('function variable variance', { |
| 630 '/main.dart': ''' | 640 '/main.dart': ''' |
| 631 | 641 |
| 632 class A {} | 642 class A {} |
| 633 class B extends A {} | 643 class B extends A {} |
| 634 | 644 |
| 635 typedef T Function2<S, T>(S z); | 645 typedef T Function2<S, T>(S z); |
| 636 | 646 |
| 637 void main() { | 647 void main() { |
| 638 { | 648 { |
| 639 Function2<B, A> top; | 649 Function2<B, A> top; |
| 640 Function2<B, B> left; | 650 Function2<B, B> left; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 656 right = right; | 666 right = right; |
| 657 right = bot; | 667 right = bot; |
| 658 | 668 |
| 659 bot = /*warning:DOWN_CAST_COMPOSITE*/top; | 669 bot = /*warning:DOWN_CAST_COMPOSITE*/top; |
| 660 bot = /*warning:DOWN_CAST_COMPOSITE*/left; | 670 bot = /*warning:DOWN_CAST_COMPOSITE*/left; |
| 661 bot = /*warning:DOWN_CAST_COMPOSITE*/right; | 671 bot = /*warning:DOWN_CAST_COMPOSITE*/right; |
| 662 bot = bot; | 672 bot = bot; |
| 663 } | 673 } |
| 664 } | 674 } |
| 665 ''' | 675 ''' |
| 666 }); | 676 }); |
| 667 | 677 |
| 668 testChecker('Function typing and subtyping: higher order function literals', { | 678 testChecker('higher order function literals 1', { |
| 669 '/main.dart': ''' | 679 '/main.dart': ''' |
| 670 | 680 |
| 671 class A {} | 681 class A {} |
| 672 class B extends A {} | 682 class B extends A {} |
| 673 | 683 |
| 674 typedef T Function2<S, T>(S z); | 684 typedef T Function2<S, T>(S z); |
| 675 | 685 |
| 676 typedef A BToA(B x); // Top of the base lattice | 686 typedef A BToA(B x); // Top of the base lattice |
| 677 typedef B AToB(A x); // Bot of the base lattice | 687 typedef B AToB(A x); // Bot of the base lattice |
| 678 | 688 |
| 679 BToA top(AToB f) => f; | 689 BToA top(AToB f) => f; |
| 680 AToB left(AToB f) => f; | 690 AToB left(AToB f) => f; |
| 681 BToA right(BToA f) => f; | 691 BToA right(BToA f) => f; |
| 682 AToB _bot(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f; | 692 AToB _bot(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f; |
| 683 AToB bot(BToA f) => f as AToB; | 693 AToB bot(BToA f) => f as AToB; |
|
Jennifer Messerly
2016/02/02 22:15:05
it's hard to see in the diff, but the original cod
| |
| 684 | 694 |
| 695 void main() { | |
| 696 { | |
| 697 Function2<AToB, BToA> f; // Top | |
| 698 f = top; | |
| 699 f = left; | |
| 700 f = right; | |
| 701 f = bot; | |
| 702 } | |
| 703 { | |
| 704 Function2<AToB, AToB> f; // Left | |
| 705 f = /*severe:STATIC_TYPE_ERROR*/top; | |
| 706 f = left; | |
| 707 f = /*severe:STATIC_TYPE_ERROR*/right; | |
| 708 f = bot; | |
| 709 } | |
| 710 { | |
| 711 Function2<BToA, BToA> f; // Right | |
| 712 f = /*severe:STATIC_TYPE_ERROR*/top; | |
| 713 f = /*severe:STATIC_TYPE_ERROR*/left; | |
| 714 f = right; | |
| 715 f = bot; | |
| 716 } | |
| 717 { | |
| 718 Function2<BToA, AToB> f; // Bot | |
| 719 f = bot; | |
| 720 f = /*severe:STATIC_TYPE_ERROR*/left; | |
| 721 f = /*severe:STATIC_TYPE_ERROR*/top; | |
| 722 f = /*severe:STATIC_TYPE_ERROR*/left; | |
| 723 } | |
| 724 } | |
| 725 ''' | |
| 726 }); | |
| 727 | |
| 728 testChecker('higher order function literals 2', { | |
| 729 '/main.dart': ''' | |
| 730 | |
| 731 class A {} | |
| 732 class B extends A {} | |
| 733 | |
| 734 typedef T Function2<S, T>(S z); | |
| 735 | |
| 736 typedef A BToA(B x); // Top of the base lattice | |
| 737 typedef B AToB(A x); // Bot of the base lattice | |
| 738 | |
| 685 Function2<B, A> top(AToB f) => f; | 739 Function2<B, A> top(AToB f) => f; |
| 686 Function2<A, B> left(AToB f) => f; | 740 Function2<A, B> left(AToB f) => f; |
| 687 Function2<B, A> right(BToA f) => f; | 741 Function2<B, A> right(BToA f) => f; |
| 688 Function2<A, B> _bot(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f; | 742 Function2<A, B> _bot(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f; |
| 689 Function2<A, B> bot(BToA f) => f as Function2<A, B>; | 743 Function2<A, B> bot(BToA f) => f as Function2<A, B>; |
| 690 | 744 |
| 745 void main() { | |
| 746 { | |
| 747 Function2<AToB, BToA> f; // Top | |
| 748 f = top; | |
| 749 f = left; | |
| 750 f = right; | |
| 751 f = bot; | |
| 752 } | |
| 753 { | |
| 754 Function2<AToB, AToB> f; // Left | |
| 755 f = /*severe:STATIC_TYPE_ERROR*/top; | |
| 756 f = left; | |
| 757 f = /*severe:STATIC_TYPE_ERROR*/right; | |
| 758 f = bot; | |
| 759 } | |
| 760 { | |
| 761 Function2<BToA, BToA> f; // Right | |
| 762 f = /*severe:STATIC_TYPE_ERROR*/top; | |
| 763 f = /*severe:STATIC_TYPE_ERROR*/left; | |
| 764 f = right; | |
| 765 f = bot; | |
| 766 } | |
| 767 { | |
| 768 Function2<BToA, AToB> f; // Bot | |
| 769 f = bot; | |
| 770 f = /*severe:STATIC_TYPE_ERROR*/left; | |
| 771 f = /*severe:STATIC_TYPE_ERROR*/top; | |
| 772 f = /*severe:STATIC_TYPE_ERROR*/left; | |
| 773 } | |
| 774 } | |
| 775 ''' | |
| 776 }); | |
| 777 | |
| 778 testChecker('higher order function literals 3', { | |
| 779 '/main.dart': ''' | |
| 780 | |
| 781 class A {} | |
| 782 class B extends A {} | |
| 783 | |
| 784 typedef T Function2<S, T>(S z); | |
| 785 | |
| 786 typedef A BToA(B x); // Top of the base lattice | |
| 787 typedef B AToB(A x); // Bot of the base lattice | |
| 691 | 788 |
| 692 BToA top(Function2<A, B> f) => f; | 789 BToA top(Function2<A, B> f) => f; |
| 693 AToB left(Function2<A, B> f) => f; | 790 AToB left(Function2<A, B> f) => f; |
| 694 BToA right(Function2<B, A> f) => f; | 791 BToA right(Function2<B, A> f) => f; |
| 695 AToB _bot(Function2<B, A> f) => /*warning:DOWN_CAST_COMPOSITE*/f; | 792 AToB _bot(Function2<B, A> f) => /*warning:DOWN_CAST_COMPOSITE*/f; |
| 696 AToB bot(Function2<B, A> f) => f as AToB; | 793 AToB bot(Function2<B, A> f) => f as AToB; |
| 697 | 794 |
| 698 void main() { | 795 void main() { |
| 699 { | 796 { |
| 700 Function2<AToB, BToA> f; // Top | 797 Function2<AToB, BToA> f; // Top |
| 701 f = top; | 798 f = top; |
| 702 f = left; | 799 f = left; |
| 703 f = right; | 800 f = right; |
| 704 f = bot; | 801 f = bot; |
| 705 } | 802 } |
| 706 { | 803 { |
| 707 Function2<AToB, AToB> f; // Left | 804 Function2<AToB, AToB> f; // Left |
| 708 f = /*warning:DOWN_CAST_COMPOSITE*/top; | 805 f = /*severe:STATIC_TYPE_ERROR*/top; |
| 709 f = left; | 806 f = left; |
| 710 f = /*warning:DOWN_CAST_COMPOSITE*/right; // Should we reject this? | 807 f = /*severe:STATIC_TYPE_ERROR*/right; |
| 711 f = bot; | 808 f = bot; |
| 712 } | 809 } |
| 713 { | 810 { |
| 714 Function2<BToA, BToA> f; // Right | 811 Function2<BToA, BToA> f; // Right |
| 715 f = /*warning:DOWN_CAST_COMPOSITE*/top; | 812 f = /*severe:STATIC_TYPE_ERROR*/top; |
| 716 f = /*warning:DOWN_CAST_COMPOSITE*/left; // Should we reject this? | 813 f = /*severe:STATIC_TYPE_ERROR*/left; |
| 717 f = right; | 814 f = right; |
| 718 f = bot; | 815 f = bot; |
| 719 } | 816 } |
| 720 { | 817 { |
| 721 Function2<BToA, AToB> f; // Bot | 818 Function2<BToA, AToB> f; // Bot |
| 722 f = bot; | 819 f = bot; |
| 723 f = /*warning:DOWN_CAST_COMPOSITE*/left; | 820 f = /*severe:STATIC_TYPE_ERROR*/left; |
| 724 f = /*warning:DOWN_CAST_COMPOSITE*/top; | 821 f = /*severe:STATIC_TYPE_ERROR*/top; |
| 725 f = /*warning:DOWN_CAST_COMPOSITE*/left; | 822 f = /*severe:STATIC_TYPE_ERROR*/left; |
| 726 } | 823 } |
| 727 } | 824 } |
| 728 ''' | 825 ''' |
| 729 }); | 826 }); |
| 730 | 827 |
| 731 testChecker( | 828 testChecker('higher order function variables', { |
| 732 'Function typing and subtyping: higher order function variables', { | 829 '/main.dart': ''' |
| 733 '/main.dart': ''' | |
| 734 | 830 |
| 735 class A {} | 831 class A {} |
| 736 class B extends A {} | 832 class B extends A {} |
| 737 | 833 |
| 738 typedef T Function2<S, T>(S z); | 834 typedef T Function2<S, T>(S z); |
| 739 | 835 |
| 740 void main() { | 836 void main() { |
| 741 { | 837 { |
| 742 Function2<Function2<A, B>, Function2<B, A>> top; | 838 Function2<Function2<A, B>, Function2<B, A>> top; |
| 743 Function2<Function2<B, A>, Function2<B, A>> right; | 839 Function2<Function2<B, A>, Function2<B, A>> right; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 761 right = right; | 857 right = right; |
| 762 right = bot; | 858 right = bot; |
| 763 | 859 |
| 764 bot = /*warning:DOWN_CAST_COMPOSITE*/top; | 860 bot = /*warning:DOWN_CAST_COMPOSITE*/top; |
| 765 bot = /*warning:DOWN_CAST_COMPOSITE*/left; | 861 bot = /*warning:DOWN_CAST_COMPOSITE*/left; |
| 766 bot = /*warning:DOWN_CAST_COMPOSITE*/right; | 862 bot = /*warning:DOWN_CAST_COMPOSITE*/right; |
| 767 bot = bot; | 863 bot = bot; |
| 768 } | 864 } |
| 769 } | 865 } |
| 770 ''' | 866 ''' |
| 771 }); | 867 }); |
| 772 | 868 |
| 773 testChecker('Function typing and subtyping: named and optional parameters', { | 869 testChecker('named and optional parameters', { |
| 774 '/main.dart': ''' | 870 '/main.dart': ''' |
| 775 | 871 |
| 776 class A {} | 872 class A {} |
| 777 | 873 |
| 778 typedef A FR(A x); | 874 typedef A FR(A x); |
| 779 typedef A FO([A x]); | 875 typedef A FO([A x]); |
| 780 typedef A FN({A x}); | 876 typedef A FN({A x}); |
| 781 typedef A FRR(A x, A y); | 877 typedef A FRR(A x, A y); |
| 782 typedef A FRO(A x, [A y]); | 878 typedef A FRO(A x, [A y]); |
| 783 typedef A FRN(A x, {A n}); | 879 typedef A FRN(A x, {A n}); |
| 784 typedef A FOO([A x, A y]); | 880 typedef A FOO([A x, A y]); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 880 nnn = /*severe:STATIC_TYPE_ERROR*/o; | 976 nnn = /*severe:STATIC_TYPE_ERROR*/o; |
| 881 nnn = /*warning:DOWN_CAST_COMPOSITE*/n; | 977 nnn = /*warning:DOWN_CAST_COMPOSITE*/n; |
| 882 nnn = /*severe:STATIC_TYPE_ERROR*/rr; | 978 nnn = /*severe:STATIC_TYPE_ERROR*/rr; |
| 883 nnn = /*severe:STATIC_TYPE_ERROR*/ro; | 979 nnn = /*severe:STATIC_TYPE_ERROR*/ro; |
| 884 nnn = /*severe:STATIC_TYPE_ERROR*/rn; | 980 nnn = /*severe:STATIC_TYPE_ERROR*/rn; |
| 885 nnn = /*severe:STATIC_TYPE_ERROR*/oo; | 981 nnn = /*severe:STATIC_TYPE_ERROR*/oo; |
| 886 nnn = /*warning:DOWN_CAST_COMPOSITE*/nn; | 982 nnn = /*warning:DOWN_CAST_COMPOSITE*/nn; |
| 887 nnn = nnn; | 983 nnn = nnn; |
| 888 } | 984 } |
| 889 ''' | 985 ''' |
| 890 }); | 986 }); |
| 891 | 987 |
| 892 testChecker('Function subtyping: objects with call methods', { | 988 testChecker('Function subtyping: objects with call methods', { |
| 893 '/main.dart': ''' | 989 '/main.dart': ''' |
| 894 | 990 |
| 895 typedef int I2I(int x); | 991 typedef int I2I(int x); |
| 896 typedef num N2N(num x); | 992 typedef num N2N(num x); |
| 897 class A { | 993 class A { |
| 898 int call(int x) => x; | 994 int call(int x) => x; |
| 899 } | 995 } |
| 900 class B { | 996 class B { |
| 901 num call(num x) => x; | 997 num call(num x) => x; |
| 902 } | 998 } |
| 903 int i2i(int x) => x; | 999 int i2i(int x) => x; |
| 904 num n2n(num x) => x; | 1000 num n2n(num x) => x; |
| 905 void main() { | 1001 void main() { |
| 906 { | 1002 { |
| 907 I2I f; | 1003 I2I f; |
| 908 f = new A(); | 1004 f = new A(); |
| 909 f = /*severe:STATIC_TYPE_ERROR*/new B(); | 1005 f = /*severe:STATIC_TYPE_ERROR*/new B(); |
| 910 f = i2i; | 1006 f = i2i; |
| 911 f = /*warning:DOWN_CAST_COMPOSITE*/n2n; | 1007 f = /*severe:STATIC_TYPE_ERROR*/n2n; |
| 912 f = /*warning:DOWN_CAST_COMPOSITE*/i2i as Object; | 1008 f = /*warning:DOWN_CAST_COMPOSITE*/i2i as Object; |
| 913 f = /*warning:DOWN_CAST_COMPOSITE*/n2n as Function; | 1009 f = /*warning:DOWN_CAST_COMPOSITE*/n2n as Function; |
| 914 } | 1010 } |
| 915 { | 1011 { |
| 916 N2N f; | 1012 N2N f; |
| 917 f = /*severe:STATIC_TYPE_ERROR*/new A(); | 1013 f = /*severe:STATIC_TYPE_ERROR*/new A(); |
| 918 f = new B(); | 1014 f = new B(); |
| 919 f = /*warning:DOWN_CAST_COMPOSITE*/i2i; | 1015 f = /*severe:STATIC_TYPE_ERROR*/i2i; |
| 920 f = n2n; | 1016 f = n2n; |
| 921 f = /*warning:DOWN_CAST_COMPOSITE*/i2i as Object; | 1017 f = /*warning:DOWN_CAST_COMPOSITE*/i2i as Object; |
| 922 f = /*warning:DOWN_CAST_COMPOSITE*/n2n as Function; | 1018 f = /*warning:DOWN_CAST_COMPOSITE*/n2n as Function; |
| 923 } | 1019 } |
| 924 { | 1020 { |
| 925 A f; | 1021 A f; |
| 926 f = new A(); | 1022 f = new A(); |
| 927 f = /*severe:STATIC_TYPE_ERROR*/new B(); | 1023 f = /*severe:STATIC_TYPE_ERROR*/new B(); |
| 928 f = /*severe:STATIC_TYPE_ERROR*/i2i; | 1024 f = /*severe:STATIC_TYPE_ERROR*/i2i; |
| 929 f = /*severe:STATIC_TYPE_ERROR*/n2n; | 1025 f = /*severe:STATIC_TYPE_ERROR*/n2n; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 943 Function f; | 1039 Function f; |
| 944 f = new A(); | 1040 f = new A(); |
| 945 f = new B(); | 1041 f = new B(); |
| 946 f = i2i; | 1042 f = i2i; |
| 947 f = n2n; | 1043 f = n2n; |
| 948 f = /*info:DOWN_CAST_IMPLICIT*/i2i as Object; | 1044 f = /*info:DOWN_CAST_IMPLICIT*/i2i as Object; |
| 949 f = (n2n as Function); | 1045 f = (n2n as Function); |
| 950 } | 1046 } |
| 951 } | 1047 } |
| 952 ''' | 1048 ''' |
| 953 }); | 1049 }); |
| 954 | 1050 |
| 955 testChecker('Function typing and subtyping: void', { | 1051 testChecker('void', { |
| 956 '/main.dart': ''' | 1052 '/main.dart': ''' |
| 957 | 1053 |
| 958 class A { | 1054 class A { |
| 959 void bar() => null; | 1055 void bar() => null; |
| 960 void foo() => bar; // allowed | 1056 void foo() => bar; // allowed |
| 961 } | 1057 } |
| 962 ''' | 1058 ''' |
| 963 }); | 1059 }); |
| 964 | 1060 |
| 965 testChecker('Function subtyping: uninferred closure', { | 1061 testChecker('uninferred closure', { |
| 966 '/main.dart': ''' | 1062 '/main.dart': ''' |
| 967 typedef num Num2Num(num x); | 1063 typedef num Num2Num(num x); |
| 968 void main() { | 1064 void main() { |
| 969 Num2Num g = /*info:INFERRED_TYPE_CLOSURE,severe:STATIC_TYPE_ERROR*/(int x) { return x; }; | 1065 Num2Num g = /*info:INFERRED_TYPE_CLOSURE,severe:STATIC_TYPE_ERROR*/(int x) { return x; }; |
| 970 print(g(42)); | 1066 print(g(42)); |
| 971 } | 1067 } |
| 972 ''' | 1068 ''' |
| 1069 }); | |
| 973 }); | 1070 }); |
| 974 | 1071 |
| 975 testChecker('Relaxed casts', { | 1072 testChecker('Relaxed casts', { |
| 976 '/main.dart': ''' | 1073 '/main.dart': ''' |
| 977 | 1074 |
| 978 class A {} | 1075 class A {} |
| 979 | 1076 |
| 980 class L<T> {} | 1077 class L<T> {} |
| 981 class M<T> extends L<T> {} | 1078 class M<T> extends L<T> {} |
| 982 // L<dynamic|Object> | 1079 // L<dynamic|Object> |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1409 /*=S*/ then/*<S>*/(Object onValue(T t)) => null; | 1506 /*=S*/ then/*<S>*/(Object onValue(T t)) => null; |
| 1410 } | 1507 } |
| 1411 | 1508 |
| 1412 class DerivedFuture4<A> extends Future<A> { | 1509 class DerivedFuture4<A> extends Future<A> { |
| 1413 /*=B*/ then/*<B>*/(Object onValue(A a)) => null; | 1510 /*=B*/ then/*<B>*/(Object onValue(A a)) => null; |
| 1414 } | 1511 } |
| 1415 ''' | 1512 ''' |
| 1416 }); | 1513 }); |
| 1417 | 1514 |
| 1418 testChecker('generic function wrong number of arguments', { | 1515 testChecker('generic function wrong number of arguments', { |
| 1419 '/main.dart': r''' | 1516 '/main.dart': r''' |
| 1420 /*=T*/ foo/*<T>*/(/*=T*/ x, /*=T*/ y) => x; | 1517 /*=T*/ foo/*<T>*/(/*=T*/ x, /*=T*/ y) => x; |
| 1421 /*=T*/ bar/*<T>*/({/*=T*/ x, /*=T*/ y}) => x; | 1518 /*=T*/ bar/*<T>*/({/*=T*/ x, /*=T*/ y}) => x; |
| 1422 | 1519 |
| 1423 main() { | 1520 main() { |
| 1424 // resolving thses shouldn't crash. | 1521 // resolving thses shouldn't crash. |
| 1425 foo(1, 2, 3); | 1522 foo(1, 2, 3); |
| 1426 String x = foo('1', '2', '3'); | 1523 String x = foo('1', '2', '3'); |
| 1427 foo(1); | 1524 foo(1); |
| 1428 String x = foo('1'); | 1525 String x = foo('1'); |
| 1429 x = /*severe:STATIC_TYPE_ERROR*/foo(1, 2, 3); | 1526 x = /*severe:STATIC_TYPE_ERROR*/foo(1, 2, 3); |
| (...skipping 1130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2560 | 2657 |
| 2561 baz1() sync* { yield* (/*info:DYNAMIC_CAST*/x); } | 2658 baz1() sync* { yield* (/*info:DYNAMIC_CAST*/x); } |
| 2562 Iterable baz2() sync* { yield* (/*info:DYNAMIC_CAST*/x); } | 2659 Iterable baz2() sync* { yield* (/*info:DYNAMIC_CAST*/x); } |
| 2563 Iterable<int> baz3() sync* { yield* (/*warning:DOWN_CAST_COMPOSITE*/x); } | 2660 Iterable<int> baz3() sync* { yield* (/*warning:DOWN_CAST_COMPOSITE*/x); } |
| 2564 Iterable<int> baz4() sync* { yield* new Iterable<int>(); } | 2661 Iterable<int> baz4() sync* { yield* new Iterable<int>(); } |
| 2565 Iterable<int> baz5() sync* { yield* (/*info:INFERRED_TYPE_ALLOCATION*/ne w Iterable()); } | 2662 Iterable<int> baz5() sync* { yield* (/*info:INFERRED_TYPE_ALLOCATION*/ne w Iterable()); } |
| 2566 ''' | 2663 ''' |
| 2567 }); | 2664 }); |
| 2568 }); | 2665 }); |
| 2569 } | 2666 } |
| OLD | NEW |