| 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; |
| 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; |
| 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('static method variance', { |
| 669 '/main.dart': ''' | 679 '/main.dart': ''' |
| 670 | 680 |
| 671 class A {} | 681 class A {} |
| 672 class B extends A {} | 682 class B extends A {} |
| 683 |
| 684 class C { |
| 685 static A top(B x) => x; |
| 686 static B left(B x) => x; |
| 687 static A right(A x) => x; |
| 688 static B bot(A x) => x as B; |
| 689 } |
| 690 |
| 691 typedef T Function2<S, T>(S z); |
| 692 |
| 693 void main() { |
| 694 { |
| 695 Function2<B, A> f; |
| 696 f = C.top; |
| 697 f = C.left; |
| 698 f = C.right; |
| 699 f = C.bot; |
| 700 } |
| 701 { |
| 702 Function2<B, B> f; |
| 703 f = /*severe:STATIC_TYPE_ERROR*/C.top; |
| 704 f = C.left; |
| 705 f = /*severe:STATIC_TYPE_ERROR*/C.right; |
| 706 f = C.bot; |
| 707 } |
| 708 { |
| 709 Function2<A, A> f; |
| 710 f = /*severe:STATIC_TYPE_ERROR*/C.top; |
| 711 f = /*severe:STATIC_TYPE_ERROR*/C.left; |
| 712 f = C.right; |
| 713 f = C.bot; |
| 714 } |
| 715 { |
| 716 Function2<A, B> f; |
| 717 f = /*severe:STATIC_TYPE_ERROR*/C.top; |
| 718 f = /*severe:STATIC_TYPE_ERROR*/C.left; |
| 719 f = /*severe:STATIC_TYPE_ERROR*/C.right; |
| 720 f = C.bot; |
| 721 } |
| 722 } |
| 723 ''' |
| 724 }); |
| 725 |
| 726 testChecker('instance method variance', { |
| 727 '/main.dart': ''' |
| 728 |
| 729 class A {} |
| 730 class B extends A {} |
| 731 |
| 732 class C { |
| 733 A top(B x) => x; |
| 734 B left(B x) => x; |
| 735 A right(A x) => x; |
| 736 B bot(A x) => x as B; |
| 737 } |
| 738 |
| 739 typedef T Function2<S, T>(S z); |
| 740 |
| 741 void main() { |
| 742 C c = new C(); |
| 743 { |
| 744 Function2<B, A> f; |
| 745 f = c.top; |
| 746 f = c.left; |
| 747 f = c.right; |
| 748 f = c.bot; |
| 749 } |
| 750 { |
| 751 Function2<B, B> f; |
| 752 f = /*warning:DOWN_CAST_COMPOSITE*/c.top; |
| 753 f = c.left; |
| 754 f = /*warning:DOWN_CAST_COMPOSITE*/c.right; |
| 755 f = c.bot; |
| 756 } |
| 757 { |
| 758 Function2<A, A> f; |
| 759 f = /*warning:DOWN_CAST_COMPOSITE*/c.top; |
| 760 f = /*warning:DOWN_CAST_COMPOSITE*/c.left; |
| 761 f = c.right; |
| 762 f = c.bot; |
| 763 } |
| 764 { |
| 765 Function2<A, B> f; |
| 766 f = /*warning:DOWN_CAST_COMPOSITE*/c.top; |
| 767 f = /*warning:DOWN_CAST_COMPOSITE*/c.left; |
| 768 f = /*warning:DOWN_CAST_COMPOSITE*/c.right; |
| 769 f = c.bot; |
| 770 } |
| 771 } |
| 772 ''' |
| 773 }); |
| 774 |
| 775 testChecker('higher order function literals 1', { |
| 776 '/main.dart': ''' |
| 777 |
| 778 class A {} |
| 779 class B extends A {} |
| 673 | 780 |
| 674 typedef T Function2<S, T>(S z); | 781 typedef T Function2<S, T>(S z); |
| 675 | 782 |
| 676 typedef A BToA(B x); // Top of the base lattice | 783 typedef A BToA(B x); // Top of the base lattice |
| 677 typedef B AToB(A x); // Bot of the base lattice | 784 typedef B AToB(A x); // Bot of the base lattice |
| 678 | 785 |
| 679 BToA top(AToB f) => f; | 786 BToA top(AToB f) => f; |
| 680 AToB left(AToB f) => f; | 787 AToB left(AToB f) => f; |
| 681 BToA right(BToA f) => f; | 788 BToA right(BToA f) => f; |
| 682 AToB _bot(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f; | 789 AToB _bot(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f; |
| 683 AToB bot(BToA f) => f as AToB; | 790 AToB bot(BToA f) => f as AToB; |
| 684 | 791 |
| 792 void main() { |
| 793 { |
| 794 Function2<AToB, BToA> f; // Top |
| 795 f = top; |
| 796 f = left; |
| 797 f = right; |
| 798 f = bot; |
| 799 } |
| 800 { |
| 801 Function2<AToB, AToB> f; // Left |
| 802 f = /*severe:STATIC_TYPE_ERROR*/top; |
| 803 f = left; |
| 804 f = /*severe:STATIC_TYPE_ERROR*/right; |
| 805 f = bot; |
| 806 } |
| 807 { |
| 808 Function2<BToA, BToA> f; // Right |
| 809 f = /*severe:STATIC_TYPE_ERROR*/top; |
| 810 f = /*severe:STATIC_TYPE_ERROR*/left; |
| 811 f = right; |
| 812 f = bot; |
| 813 } |
| 814 { |
| 815 Function2<BToA, AToB> f; // Bot |
| 816 f = bot; |
| 817 f = /*severe:STATIC_TYPE_ERROR*/left; |
| 818 f = /*severe:STATIC_TYPE_ERROR*/top; |
| 819 f = /*severe:STATIC_TYPE_ERROR*/left; |
| 820 } |
| 821 } |
| 822 ''' |
| 823 }); |
| 824 |
| 825 testChecker('higher order function literals 2', { |
| 826 '/main.dart': ''' |
| 827 |
| 828 class A {} |
| 829 class B extends A {} |
| 830 |
| 831 typedef T Function2<S, T>(S z); |
| 832 |
| 833 typedef A BToA(B x); // Top of the base lattice |
| 834 typedef B AToB(A x); // Bot of the base lattice |
| 835 |
| 685 Function2<B, A> top(AToB f) => f; | 836 Function2<B, A> top(AToB f) => f; |
| 686 Function2<A, B> left(AToB f) => f; | 837 Function2<A, B> left(AToB f) => f; |
| 687 Function2<B, A> right(BToA f) => f; | 838 Function2<B, A> right(BToA f) => f; |
| 688 Function2<A, B> _bot(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f; | 839 Function2<A, B> _bot(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f; |
| 689 Function2<A, B> bot(BToA f) => f as Function2<A, B>; | 840 Function2<A, B> bot(BToA f) => f as Function2<A, B>; |
| 690 | 841 |
| 842 void main() { |
| 843 { |
| 844 Function2<AToB, BToA> f; // Top |
| 845 f = top; |
| 846 f = left; |
| 847 f = right; |
| 848 f = bot; |
| 849 } |
| 850 { |
| 851 Function2<AToB, AToB> f; // Left |
| 852 f = /*severe:STATIC_TYPE_ERROR*/top; |
| 853 f = left; |
| 854 f = /*severe:STATIC_TYPE_ERROR*/right; |
| 855 f = bot; |
| 856 } |
| 857 { |
| 858 Function2<BToA, BToA> f; // Right |
| 859 f = /*severe:STATIC_TYPE_ERROR*/top; |
| 860 f = /*severe:STATIC_TYPE_ERROR*/left; |
| 861 f = right; |
| 862 f = bot; |
| 863 } |
| 864 { |
| 865 Function2<BToA, AToB> f; // Bot |
| 866 f = bot; |
| 867 f = /*severe:STATIC_TYPE_ERROR*/left; |
| 868 f = /*severe:STATIC_TYPE_ERROR*/top; |
| 869 f = /*severe:STATIC_TYPE_ERROR*/left; |
| 870 } |
| 871 } |
| 872 ''' |
| 873 }); |
| 874 |
| 875 testChecker('higher order function literals 3', { |
| 876 '/main.dart': ''' |
| 877 |
| 878 class A {} |
| 879 class B extends A {} |
| 880 |
| 881 typedef T Function2<S, T>(S z); |
| 882 |
| 883 typedef A BToA(B x); // Top of the base lattice |
| 884 typedef B AToB(A x); // Bot of the base lattice |
| 691 | 885 |
| 692 BToA top(Function2<A, B> f) => f; | 886 BToA top(Function2<A, B> f) => f; |
| 693 AToB left(Function2<A, B> f) => f; | 887 AToB left(Function2<A, B> f) => f; |
| 694 BToA right(Function2<B, A> f) => f; | 888 BToA right(Function2<B, A> f) => f; |
| 695 AToB _bot(Function2<B, A> f) => /*warning:DOWN_CAST_COMPOSITE*/f; | 889 AToB _bot(Function2<B, A> f) => /*warning:DOWN_CAST_COMPOSITE*/f; |
| 696 AToB bot(Function2<B, A> f) => f as AToB; | 890 AToB bot(Function2<B, A> f) => f as AToB; |
| 697 | 891 |
| 698 void main() { | 892 void main() { |
| 699 { | 893 { |
| 700 Function2<AToB, BToA> f; // Top | 894 Function2<AToB, BToA> f; // Top |
| 701 f = top; | 895 f = top; |
| 702 f = left; | 896 f = left; |
| 703 f = right; | 897 f = right; |
| 704 f = bot; | 898 f = bot; |
| 705 } | 899 } |
| 706 { | 900 { |
| 707 Function2<AToB, AToB> f; // Left | 901 Function2<AToB, AToB> f; // Left |
| 708 f = /*warning:DOWN_CAST_COMPOSITE*/top; | 902 f = /*severe:STATIC_TYPE_ERROR*/top; |
| 709 f = left; | 903 f = left; |
| 710 f = /*warning:DOWN_CAST_COMPOSITE*/right; // Should we reject this? | 904 f = /*severe:STATIC_TYPE_ERROR*/right; |
| 711 f = bot; | 905 f = bot; |
| 712 } | 906 } |
| 713 { | 907 { |
| 714 Function2<BToA, BToA> f; // Right | 908 Function2<BToA, BToA> f; // Right |
| 715 f = /*warning:DOWN_CAST_COMPOSITE*/top; | 909 f = /*severe:STATIC_TYPE_ERROR*/top; |
| 716 f = /*warning:DOWN_CAST_COMPOSITE*/left; // Should we reject this? | 910 f = /*severe:STATIC_TYPE_ERROR*/left; |
| 717 f = right; | 911 f = right; |
| 718 f = bot; | 912 f = bot; |
| 719 } | 913 } |
| 720 { | 914 { |
| 721 Function2<BToA, AToB> f; // Bot | 915 Function2<BToA, AToB> f; // Bot |
| 722 f = bot; | 916 f = bot; |
| 723 f = /*warning:DOWN_CAST_COMPOSITE*/left; | 917 f = /*severe:STATIC_TYPE_ERROR*/left; |
| 724 f = /*warning:DOWN_CAST_COMPOSITE*/top; | 918 f = /*severe:STATIC_TYPE_ERROR*/top; |
| 725 f = /*warning:DOWN_CAST_COMPOSITE*/left; | 919 f = /*severe:STATIC_TYPE_ERROR*/left; |
| 726 } | 920 } |
| 727 } | 921 } |
| 728 ''' | 922 ''' |
| 729 }); | 923 }); |
| 730 | 924 |
| 731 testChecker( | 925 testChecker('higher order function variables', { |
| 732 'Function typing and subtyping: higher order function variables', { | 926 '/main.dart': ''' |
| 733 '/main.dart': ''' | |
| 734 | 927 |
| 735 class A {} | 928 class A {} |
| 736 class B extends A {} | 929 class B extends A {} |
| 737 | 930 |
| 738 typedef T Function2<S, T>(S z); | 931 typedef T Function2<S, T>(S z); |
| 739 | 932 |
| 740 void main() { | 933 void main() { |
| 741 { | 934 { |
| 742 Function2<Function2<A, B>, Function2<B, A>> top; | 935 Function2<Function2<A, B>, Function2<B, A>> top; |
| 743 Function2<Function2<B, A>, Function2<B, A>> right; | 936 Function2<Function2<B, A>, Function2<B, A>> right; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 761 right = right; | 954 right = right; |
| 762 right = bot; | 955 right = bot; |
| 763 | 956 |
| 764 bot = /*warning:DOWN_CAST_COMPOSITE*/top; | 957 bot = /*warning:DOWN_CAST_COMPOSITE*/top; |
| 765 bot = /*warning:DOWN_CAST_COMPOSITE*/left; | 958 bot = /*warning:DOWN_CAST_COMPOSITE*/left; |
| 766 bot = /*warning:DOWN_CAST_COMPOSITE*/right; | 959 bot = /*warning:DOWN_CAST_COMPOSITE*/right; |
| 767 bot = bot; | 960 bot = bot; |
| 768 } | 961 } |
| 769 } | 962 } |
| 770 ''' | 963 ''' |
| 771 }); | 964 }); |
| 772 | 965 |
| 773 testChecker('Function typing and subtyping: named and optional parameters', { | 966 testChecker('named and optional parameters', { |
| 774 '/main.dart': ''' | 967 '/main.dart': ''' |
| 775 | 968 |
| 776 class A {} | 969 class A {} |
| 777 | 970 |
| 778 typedef A FR(A x); | 971 typedef A FR(A x); |
| 779 typedef A FO([A x]); | 972 typedef A FO([A x]); |
| 780 typedef A FN({A x}); | 973 typedef A FN({A x}); |
| 781 typedef A FRR(A x, A y); | 974 typedef A FRR(A x, A y); |
| 782 typedef A FRO(A x, [A y]); | 975 typedef A FRO(A x, [A y]); |
| 783 typedef A FRN(A x, {A n}); | 976 typedef A FRN(A x, {A n}); |
| 784 typedef A FOO([A x, A y]); | 977 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; | 1073 nnn = /*severe:STATIC_TYPE_ERROR*/o; |
| 881 nnn = /*warning:DOWN_CAST_COMPOSITE*/n; | 1074 nnn = /*warning:DOWN_CAST_COMPOSITE*/n; |
| 882 nnn = /*severe:STATIC_TYPE_ERROR*/rr; | 1075 nnn = /*severe:STATIC_TYPE_ERROR*/rr; |
| 883 nnn = /*severe:STATIC_TYPE_ERROR*/ro; | 1076 nnn = /*severe:STATIC_TYPE_ERROR*/ro; |
| 884 nnn = /*severe:STATIC_TYPE_ERROR*/rn; | 1077 nnn = /*severe:STATIC_TYPE_ERROR*/rn; |
| 885 nnn = /*severe:STATIC_TYPE_ERROR*/oo; | 1078 nnn = /*severe:STATIC_TYPE_ERROR*/oo; |
| 886 nnn = /*warning:DOWN_CAST_COMPOSITE*/nn; | 1079 nnn = /*warning:DOWN_CAST_COMPOSITE*/nn; |
| 887 nnn = nnn; | 1080 nnn = nnn; |
| 888 } | 1081 } |
| 889 ''' | 1082 ''' |
| 890 }); | 1083 }); |
| 891 | 1084 |
| 892 testChecker('Function subtyping: objects with call methods', { | 1085 testChecker('Function subtyping: objects with call methods', { |
| 893 '/main.dart': ''' | 1086 '/main.dart': ''' |
| 894 | 1087 |
| 895 typedef int I2I(int x); | 1088 typedef int I2I(int x); |
| 896 typedef num N2N(num x); | 1089 typedef num N2N(num x); |
| 897 class A { | 1090 class A { |
| 898 int call(int x) => x; | 1091 int call(int x) => x; |
| 899 } | 1092 } |
| 900 class B { | 1093 class B { |
| 901 num call(num x) => x; | 1094 num call(num x) => x; |
| 902 } | 1095 } |
| 903 int i2i(int x) => x; | 1096 int i2i(int x) => x; |
| 904 num n2n(num x) => x; | 1097 num n2n(num x) => x; |
| 905 void main() { | 1098 void main() { |
| 906 { | 1099 { |
| 907 I2I f; | 1100 I2I f; |
| 908 f = new A(); | 1101 f = new A(); |
| 909 f = /*severe:STATIC_TYPE_ERROR*/new B(); | 1102 f = /*severe:STATIC_TYPE_ERROR*/new B(); |
| 910 f = i2i; | 1103 f = i2i; |
| 911 f = /*warning:DOWN_CAST_COMPOSITE*/n2n; | 1104 f = /*severe:STATIC_TYPE_ERROR*/n2n; |
| 912 f = /*warning:DOWN_CAST_COMPOSITE*/i2i as Object; | 1105 f = /*warning:DOWN_CAST_COMPOSITE*/i2i as Object; |
| 913 f = /*warning:DOWN_CAST_COMPOSITE*/n2n as Function; | 1106 f = /*warning:DOWN_CAST_COMPOSITE*/n2n as Function; |
| 914 } | 1107 } |
| 915 { | 1108 { |
| 916 N2N f; | 1109 N2N f; |
| 917 f = /*severe:STATIC_TYPE_ERROR*/new A(); | 1110 f = /*severe:STATIC_TYPE_ERROR*/new A(); |
| 918 f = new B(); | 1111 f = new B(); |
| 919 f = /*warning:DOWN_CAST_COMPOSITE*/i2i; | 1112 f = /*severe:STATIC_TYPE_ERROR*/i2i; |
| 920 f = n2n; | 1113 f = n2n; |
| 921 f = /*warning:DOWN_CAST_COMPOSITE*/i2i as Object; | 1114 f = /*warning:DOWN_CAST_COMPOSITE*/i2i as Object; |
| 922 f = /*warning:DOWN_CAST_COMPOSITE*/n2n as Function; | 1115 f = /*warning:DOWN_CAST_COMPOSITE*/n2n as Function; |
| 923 } | 1116 } |
| 924 { | 1117 { |
| 925 A f; | 1118 A f; |
| 926 f = new A(); | 1119 f = new A(); |
| 927 f = /*severe:STATIC_TYPE_ERROR*/new B(); | 1120 f = /*severe:STATIC_TYPE_ERROR*/new B(); |
| 928 f = /*severe:STATIC_TYPE_ERROR*/i2i; | 1121 f = /*severe:STATIC_TYPE_ERROR*/i2i; |
| 929 f = /*severe:STATIC_TYPE_ERROR*/n2n; | 1122 f = /*severe:STATIC_TYPE_ERROR*/n2n; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 943 Function f; | 1136 Function f; |
| 944 f = new A(); | 1137 f = new A(); |
| 945 f = new B(); | 1138 f = new B(); |
| 946 f = i2i; | 1139 f = i2i; |
| 947 f = n2n; | 1140 f = n2n; |
| 948 f = /*info:DOWN_CAST_IMPLICIT*/i2i as Object; | 1141 f = /*info:DOWN_CAST_IMPLICIT*/i2i as Object; |
| 949 f = (n2n as Function); | 1142 f = (n2n as Function); |
| 950 } | 1143 } |
| 951 } | 1144 } |
| 952 ''' | 1145 ''' |
| 953 }); | 1146 }); |
| 954 | 1147 |
| 955 testChecker('Function typing and subtyping: void', { | 1148 testChecker('void', { |
| 956 '/main.dart': ''' | 1149 '/main.dart': ''' |
| 957 | 1150 |
| 958 class A { | 1151 class A { |
| 959 void bar() => null; | 1152 void bar() => null; |
| 960 void foo() => bar; // allowed | 1153 void foo() => bar; // allowed |
| 961 } | 1154 } |
| 962 ''' | 1155 ''' |
| 963 }); | 1156 }); |
| 964 | 1157 |
| 965 testChecker('Function subtyping: uninferred closure', { | 1158 testChecker('uninferred closure', { |
| 966 '/main.dart': ''' | 1159 '/main.dart': ''' |
| 967 typedef num Num2Num(num x); | 1160 typedef num Num2Num(num x); |
| 968 void main() { | 1161 void main() { |
| 969 Num2Num g = /*info:INFERRED_TYPE_CLOSURE,severe:STATIC_TYPE_ERROR*/(int
x) { return x; }; | 1162 Num2Num g = /*info:INFERRED_TYPE_CLOSURE,severe:STATIC_TYPE_ERROR*/(int
x) { return x; }; |
| 970 print(g(42)); | 1163 print(g(42)); |
| 971 } | 1164 } |
| 972 ''' | 1165 ''' |
| 1166 }); |
| 973 }); | 1167 }); |
| 974 | 1168 |
| 975 testChecker('Relaxed casts', { | 1169 testChecker('Relaxed casts', { |
| 976 '/main.dart': ''' | 1170 '/main.dart': ''' |
| 977 | 1171 |
| 978 class A {} | 1172 class A {} |
| 979 | 1173 |
| 980 class L<T> {} | 1174 class L<T> {} |
| 981 class M<T> extends L<T> {} | 1175 class M<T> extends L<T> {} |
| 982 // L<dynamic|Object> | 1176 // 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; | 1603 /*=S*/ then/*<S>*/(Object onValue(T t)) => null; |
| 1410 } | 1604 } |
| 1411 | 1605 |
| 1412 class DerivedFuture4<A> extends Future<A> { | 1606 class DerivedFuture4<A> extends Future<A> { |
| 1413 /*=B*/ then/*<B>*/(Object onValue(A a)) => null; | 1607 /*=B*/ then/*<B>*/(Object onValue(A a)) => null; |
| 1414 } | 1608 } |
| 1415 ''' | 1609 ''' |
| 1416 }); | 1610 }); |
| 1417 | 1611 |
| 1418 testChecker('generic function wrong number of arguments', { | 1612 testChecker('generic function wrong number of arguments', { |
| 1419 '/main.dart': r''' | 1613 '/main.dart': r''' |
| 1420 /*=T*/ foo/*<T>*/(/*=T*/ x, /*=T*/ y) => x; | 1614 /*=T*/ foo/*<T>*/(/*=T*/ x, /*=T*/ y) => x; |
| 1421 /*=T*/ bar/*<T>*/({/*=T*/ x, /*=T*/ y}) => x; | 1615 /*=T*/ bar/*<T>*/({/*=T*/ x, /*=T*/ y}) => x; |
| 1422 | 1616 |
| 1423 main() { | 1617 main() { |
| 1424 // resolving thses shouldn't crash. | 1618 // resolving thses shouldn't crash. |
| 1425 foo(1, 2, 3); | 1619 foo(1, 2, 3); |
| 1426 String x = foo('1', '2', '3'); | 1620 String x = foo('1', '2', '3'); |
| 1427 foo(1); | 1621 foo(1); |
| 1428 String x = foo('1'); | 1622 String x = foo('1'); |
| 1429 x = /*severe:STATIC_TYPE_ERROR*/foo(1, 2, 3); | 1623 x = /*severe:STATIC_TYPE_ERROR*/foo(1, 2, 3); |
| (...skipping 1130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2560 | 2754 |
| 2561 baz1() sync* { yield* (/*info:DYNAMIC_CAST*/x); } | 2755 baz1() sync* { yield* (/*info:DYNAMIC_CAST*/x); } |
| 2562 Iterable baz2() sync* { yield* (/*info:DYNAMIC_CAST*/x); } | 2756 Iterable baz2() sync* { yield* (/*info:DYNAMIC_CAST*/x); } |
| 2563 Iterable<int> baz3() sync* { yield* (/*warning:DOWN_CAST_COMPOSITE*/x);
} | 2757 Iterable<int> baz3() sync* { yield* (/*warning:DOWN_CAST_COMPOSITE*/x);
} |
| 2564 Iterable<int> baz4() sync* { yield* new Iterable<int>(); } | 2758 Iterable<int> baz4() sync* { yield* new Iterable<int>(); } |
| 2565 Iterable<int> baz5() sync* { yield* (/*info:INFERRED_TYPE_ALLOCATION*/ne
w Iterable()); } | 2759 Iterable<int> baz5() sync* { yield* (/*info:INFERRED_TYPE_ALLOCATION*/ne
w Iterable()); } |
| 2566 ''' | 2760 ''' |
| 2567 }); | 2761 }); |
| 2568 }); | 2762 }); |
| 2569 } | 2763 } |
| OLD | NEW |