Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(226)

Side by Side Diff: test/checker/inferred_type_test.dart

Issue 1406983003: Remove the checker and corresponding dead code (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « test/checker/dart_foobar.dart ('k') | test/checker/self_host_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 /// Tests for type inference.
6 library dev_compiler.test.inferred_type_test;
7
8 import 'package:test/test.dart';
9
10 import '../testing.dart';
11
12 void main() {
13 // Error also expected when declared type is `int`.
14 testChecker('infer type on var', {
15 '/main.dart': '''
16 test1() {
17 int x = 3;
18 x = /*severe:StaticTypeError*/"hi";
19 }
20 '''
21 });
22
23 // If inferred type is `int`, error is also reported
24 testChecker('infer type on var 2', {
25 '/main.dart': '''
26 test2() {
27 var x = 3;
28 x = /*severe:StaticTypeError*/"hi";
29 }
30 '''
31 });
32
33 testChecker('No error when declared type is `num` and assigned null.', {
34 '/main.dart': '''
35 test1() {
36 num x = 3;
37 x = null;
38 }
39 '''
40 });
41
42 testChecker('do not infer type on dynamic', {
43 '/main.dart': '''
44 test() {
45 dynamic x = 3;
46 x = "hi";
47 }
48 '''
49 });
50
51 testChecker('do not infer type when initializer is null', {
52 '/main.dart': '''
53 test() {
54 var x = null;
55 x = "hi";
56 x = 3;
57 }
58 '''
59 });
60
61 testChecker('infer type on var from field', {
62 '/main.dart': '''
63 class A {
64 int x = 0;
65
66 test1() {
67 var a = x;
68 a = /*severe:StaticTypeError*/"hi";
69 a = 3;
70 var b = y;
71 b = /*severe:StaticTypeError*/"hi";
72 b = 4;
73 var c = z;
74 c = /*severe:StaticTypeError*/"hi";
75 c = 4;
76 }
77
78 int y; // field def after use
79 final z = 42; // should infer `int`
80 }
81 '''
82 });
83
84 testChecker('infer type on var from top-level', {
85 '/main.dart': '''
86 int x = 0;
87
88 test1() {
89 var a = x;
90 a = /*severe:StaticTypeError*/"hi";
91 a = 3;
92 var b = y;
93 b = /*severe:StaticTypeError*/"hi";
94 b = 4;
95 var c = z;
96 c = /*severe:StaticTypeError*/"hi";
97 c = 4;
98 }
99
100 int y = 0; // field def after use
101 final z = 42; // should infer `int`
102 '''
103 });
104
105 testChecker('do not infer field type when initializer is null', {
106 '/main.dart': '''
107 var x = null;
108 var y = 3;
109 class A {
110 static var x = null;
111 static var y = 3;
112
113 var x2 = null;
114 var y2 = 3;
115 }
116
117 test() {
118 x = "hi";
119 y = /*severe:StaticTypeError*/"hi";
120 A.x = "hi";
121 A.y = /*severe:StaticTypeError*/"hi";
122 new A().x2 = "hi";
123 new A().y2 = /*severe:StaticTypeError*/"hi";
124 }
125 '''
126 });
127
128 testChecker('infer from variables in non-cycle imports with flag', {
129 '/a.dart': '''
130 var x = 2;
131 ''',
132 '/main.dart': '''
133 import 'a.dart';
134 var y = x;
135
136 test1() {
137 x = /*severe:StaticTypeError*/"hi";
138 y = /*severe:StaticTypeError*/"hi";
139 }
140 '''
141 });
142
143 testChecker('infer from variables in non-cycle imports with flag 2', {
144 '/a.dart': '''
145 class A { static var x = 2; }
146 ''',
147 '/main.dart': '''
148 import 'a.dart';
149 class B { static var y = A.x; }
150
151 test1() {
152 A.x = /*severe:StaticTypeError*/"hi";
153 B.y = /*severe:StaticTypeError*/"hi";
154 }
155 '''
156 });
157
158 testChecker('infer from variables in cycle libs when flag is on', {
159 '/a.dart': '''
160 import 'main.dart';
161 var x = 2; // ok to infer
162 ''',
163 '/main.dart': '''
164 import 'a.dart';
165 var y = x; // now ok :)
166
167 test1() {
168 int t = 3;
169 t = x;
170 t = y;
171 }
172 '''
173 });
174
175 testChecker('infer from variables in cycle libs when flag is on 2', {
176 '/a.dart': '''
177 import 'main.dart';
178 class A { static var x = 2; }
179 ''',
180 '/main.dart': '''
181 import 'a.dart';
182 class B { static var y = A.x; }
183
184 test1() {
185 int t = 3;
186 t = A.x;
187 t = B.y;
188 }
189 '''
190 });
191
192 testChecker('can infer also from static and instance fields (flag on)', {
193 '/a.dart': '''
194 import 'b.dart';
195 class A {
196 static final a1 = B.b1;
197 final a2 = new B().b2;
198 }
199 ''',
200 '/b.dart': '''
201 class B {
202 static final b1 = 1;
203 final b2 = 1;
204 }
205 ''',
206 '/main.dart': '''
207 import "a.dart";
208
209 test1() {
210 int x = 0;
211 // inference in A now works.
212 x = A.a1;
213 x = new A().a2;
214 }
215 '''
216 });
217
218 testChecker('inference in cycles is deterministic', {
219 '/a.dart': '''
220 import 'b.dart';
221 class A {
222 static final a1 = B.b1;
223 final a2 = new B().b2;
224 }
225 ''',
226 '/b.dart': '''
227 class B {
228 static final b1 = 1;
229 final b2 = 1;
230 }
231 ''',
232 '/c.dart': '''
233 import "main.dart"; // creates a cycle
234
235 class C {
236 static final c1 = 1;
237 final c2 = 1;
238 }
239 ''',
240 '/e.dart': '''
241 import 'a.dart';
242 part 'e2.dart';
243
244 class E {
245 static final e1 = 1;
246 static final e2 = F.f1;
247 static final e3 = A.a1;
248 final e4 = 1;
249 final e5 = new F().f2;
250 final e6 = new A().a2;
251 }
252 ''',
253 '/f.dart': '''
254 part 'f2.dart';
255 ''',
256 '/e2.dart': '''
257 class F {
258 static final f1 = 1;
259 final f2 = 1;
260 }
261 ''',
262 '/main.dart': '''
263 import "a.dart";
264 import "c.dart";
265 import "e.dart";
266
267 class D {
268 static final d1 = A.a1 + 1;
269 static final d2 = C.c1 + 1;
270 final d3 = new A().a2;
271 final d4 = new C().c2;
272 }
273
274 test1() {
275 int x = 0;
276 // inference in A works, it's not in a cycle
277 x = A.a1;
278 x = new A().a2;
279
280 // Within a cycle we allow inference when the RHS is well known, but
281 // not when it depends on other fields within the cycle
282 x = C.c1;
283 x = D.d1;
284 x = D.d2;
285 x = new C().c2;
286 x = new D().d3;
287 x = /*info:DynamicCast*/new D().d4;
288
289
290 // Similarly if the library contains parts.
291 x = E.e1;
292 x = E.e2;
293 x = E.e3;
294 x = new E().e4;
295 x = /*info:DynamicCast*/new E().e5;
296 x = new E().e6;
297 x = F.f1;
298 x = new F().f2;
299 }
300 '''
301 });
302
303 testChecker(
304 'infer from complex expressions if the outer-most value is precise', {
305 '/main.dart': '''
306 class A { int x; B operator+(other) {} }
307 class B extends A { B(ignore); }
308 var a = new A();
309 // Note: it doesn't matter that some of these refer to 'x'.
310 var b = new B(x); // allocations
311 var c1 = [x]; // list literals
312 var c2 = const [];
313 var d = {'a': 'b'}; // map literals
314 var e = new A()..x = 3; // cascades
315 var f = 2 + 3; // binary expressions are OK if the left operand
316 // is from a library in a different strongest
317 // conected component.
318 var g = -3;
319 var h = new A() + 3;
320 var i = - new A();
321 var j = null as B;
322
323 test1() {
324 a = /*severe:StaticTypeError*/"hi";
325 a = new B(3);
326 b = /*severe:StaticTypeError*/"hi";
327 b = new B(3);
328 c1 = [];
329 c1 = /*severe:StaticTypeError*/{};
330 c2 = [];
331 c2 = /*severe:StaticTypeError*/{};
332 d = {};
333 d = /*severe:StaticTypeError*/3;
334 e = new A();
335 e = /*severe:StaticTypeError*/{};
336 f = 3;
337 f = /*severe:StaticTypeError*/false;
338 g = 1;
339 g = /*severe:StaticTypeError*/false;
340 h = /*severe:StaticTypeError*/false;
341 h = new B();
342 i = false;
343 j = new B();
344 j = /*severe:StaticTypeError*/false;
345 j = /*severe:StaticTypeError*/[];
346 }
347 '''
348 });
349
350 // but flags can enable this behavior.
351 testChecker('infer if complex expressions read possibly inferred field', {
352 '/a.dart': '''
353 class A {
354 var x = 3;
355 }
356 ''',
357 '/main.dart': '''
358 import 'a.dart';
359 class B {
360 var y = 3;
361 }
362 final t1 = new A();
363 final t2 = new A().x;
364 final t3 = new B();
365 final t4 = new B().y;
366
367 test1() {
368 int i = 0;
369 A a;
370 B b;
371 a = t1;
372 i = t2;
373 b = t3;
374 i = /*info:DynamicCast*/t4;
375 i = new B().y; // B.y was inferred though
376 }
377 '''
378 });
379
380 group('infer types on loop indices', () {
381 testChecker('foreach loop', {
382 '/main.dart': '''
383 class Foo {
384 int bar = 42;
385 }
386
387 test() {
388 var list = <Foo>[];
389 for (var x in list) {
390 String y = /*severe:StaticTypeError*/x;
391 }
392
393 for (dynamic x in list) {
394 String y = /*info:DynamicCast*/x;
395 }
396
397 for (String x in /*severe:StaticTypeError*/list) {
398 String y = x;
399 }
400
401 var z;
402 for(z in list) {
403 String y = /*info:DynamicCast*/z;
404 }
405
406 Iterable iter = list;
407 for (Foo x in /*warning:DownCastComposite*/iter) {
408 var y = x;
409 }
410
411 dynamic iter2 = list;
412 for (Foo x in /*warning:DownCastComposite*/iter2) {
413 var y = x;
414 }
415
416 var map = <String, Foo>{};
417 // Error: map must be an Iterable.
418 for (var x in /*severe:StaticTypeError*/map) {
419 String y = /*info:DynamicCast*/x;
420 }
421
422 // We're not properly inferring that map.keys is an Iterable<String>
423 // and that x is a String.
424 for (var x in map.keys) {
425 String y = x;
426 }
427 }
428 '''
429 });
430
431 testChecker('for loop, with inference', {
432 '/main.dart': '''
433 test() {
434 for (var i = 0; i < 10; i++) {
435 int j = i + 1;
436 }
437 }
438 '''
439 });
440 });
441
442 testChecker('propagate inference to field in class', {
443 '/main.dart': '''
444 class A {
445 int x = 2;
446 }
447
448 test() {
449 var a = new A();
450 A b = a; // doesn't require down cast
451 print(a.x); // doesn't require dynamic invoke
452 print(a.x + 2); // ok to use in bigger expression
453 }
454 '''
455 });
456
457 testChecker('propagate inference to field in class dynamic warnings', {
458 '/main.dart': '''
459 class A {
460 int x = 2;
461 }
462
463 test() {
464 dynamic a = new A();
465 A b = /*info:DynamicCast*/a;
466 print(/*info:DynamicInvoke*/a.x);
467 print(/*info:DynamicInvoke*/(/*info:DynamicInvoke*/a.x) + 2);
468 }
469 '''
470 });
471
472 testChecker('propagate inference transitively', {
473 '/main.dart': '''
474 class A {
475 int x = 2;
476 }
477
478 test5() {
479 var a1 = new A();
480 a1.x = /*severe:StaticTypeError*/"hi";
481
482 A a2 = new A();
483 a2.x = /*severe:StaticTypeError*/"hi";
484 }
485 '''
486 });
487
488 testChecker('propagate inference transitively 2', {
489 '/main.dart': '''
490 class A {
491 int x = 42;
492 }
493
494 class B {
495 A a = new A();
496 }
497
498 class C {
499 B b = new B();
500 }
501
502 class D {
503 C c = new C();
504 }
505
506 void main() {
507 var d1 = new D();
508 print(d1.c.b.a.x);
509
510 D d2 = new D();
511 print(d2.c.b.a.x);
512 }
513 '''
514 });
515
516 group('infer type on overridden fields', () {
517 testChecker('2', {
518 '/main.dart': '''
519 class A {
520 int x = 2;
521 }
522
523 class B extends A {
524 get x => 3;
525 }
526
527 foo() {
528 String y = /*severe:StaticTypeError*/new B().x;
529 int z = new B().x;
530 }
531 '''
532 });
533
534 testChecker('4', {
535 '/main.dart': '''
536 class A {
537 int x = 2;
538 }
539
540 class B implements A {
541 get x => 3;
542 }
543
544 foo() {
545 String y = /*severe:StaticTypeError*/new B().x;
546 int z = new B().x;
547 }
548 '''
549 });
550 });
551
552 group('infer types on generic instantiations', () {
553 testChecker('infer', {
554 '/main.dart': '''
555 class A<T> {
556 T x;
557 }
558
559 class B implements A<int> {
560 /*severe:InvalidMethodOverride*/dynamic get x => 3;
561 }
562
563 foo() {
564 String y = /*info:DynamicCast*/new B().x;
565 int z = /*info:DynamicCast*/new B().x;
566 }
567 '''
568 });
569
570 testChecker('3', {
571 '/main.dart': '''
572 class A<T> {
573 T x;
574 T w;
575 }
576
577 class B implements A<int> {
578 get x => 3;
579 get w => /*severe:StaticTypeError*/"hello";
580 }
581
582 foo() {
583 String y = /*severe:StaticTypeError*/new B().x;
584 int z = new B().x;
585 }
586 '''
587 });
588
589 testChecker('4', {
590 '/main.dart': '''
591 class A<T> {
592 T x;
593 }
594
595 class B<E> extends A<E> {
596 E y;
597 get x => y;
598 }
599
600 foo() {
601 int y = /*severe:StaticTypeError*/new B<String>().x;
602 String z = new B<String>().x;
603 }
604 '''
605 });
606
607 testChecker('5', {
608 '/main.dart': '''
609 abstract class I<E> {
610 String m(a, String f(v, T e));
611 }
612
613 abstract class A<E> implements I<E> {
614 const A();
615 String m(a, String f(v, T e));
616 }
617
618 abstract class M {
619 int y;
620 }
621
622 class B<E> extends A<E> implements M {
623 const B();
624 int get y => 0;
625
626 m(a, f(v, T e)) {}
627 }
628
629 foo () {
630 int y = /*severe:StaticTypeError*/new B().m(null, null);
631 String z = new B().m(null, null);
632 }
633 '''
634 });
635 });
636
637 testChecker('infer type regardless of declaration order or cycles', {
638 '/b.dart': '''
639 import 'main.dart';
640
641 class B extends A { }
642 ''',
643 '/main.dart': '''
644 import 'b.dart';
645 class C extends B {
646 get x;
647 }
648 class A {
649 int get x;
650 }
651 foo () {
652 int y = new C().x;
653 String y = /*severe:StaticTypeError*/new C().x;
654 }
655 '''
656 });
657
658 // Note: this is a regression test for a non-deterministic behavior we used to
659 // have with inference in library cycles. If you see this test flake out,
660 // change `test` to `skip_test` and reopen bug #48.
661 testChecker('infer types on generic instantiations in library cycle', {
662 '/a.dart': '''
663 import 'main.dart';
664 abstract class I<E> {
665 A<E> m(a, String f(v, int e));
666 }
667 ''',
668 '/main.dart': '''
669 import 'a.dart';
670
671 abstract class A<E> implements I<E> {
672 const A();
673
674 E value;
675 }
676
677 abstract class M {
678 int y;
679 }
680
681 class B<E> extends A<E> implements M {
682 const B();
683 int get y => 0;
684
685 m(a, f(v, int e)) {}
686 }
687
688 foo () {
689 int y = /*severe:StaticTypeError*/new B<String>().m(null, null).value;
690 String z = new B<String>().m(null, null).value;
691 }
692 '''
693 });
694
695 group('do not infer overridden fields that explicitly say dynamic', () {
696 testChecker('infer', {
697 '/main.dart': '''
698 class A {
699 int x = 2;
700 }
701
702 class B implements A {
703 /*severe:InvalidMethodOverride*/dynamic get x => 3;
704 }
705
706 foo() {
707 String y = /*info:DynamicCast*/new B().x;
708 int z = /*info:DynamicCast*/new B().x;
709 }
710 '''
711 });
712 });
713
714 testChecker('conflicts can happen', {
715 '/main.dart': '''
716 class I1 {
717 int x;
718 }
719 class I2 extends I1 {
720 int y;
721 }
722
723 class A {
724 final I1 a;
725 }
726
727 class B {
728 final I2 a;
729 }
730
731 class C1 extends A implements B {
732 /*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/get a => null;
733 }
734
735 // Still ambiguous
736 class C2 extends B implements A {
737 /*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/get a => null;
738 }
739 '''
740 });
741
742 testChecker('conflicts can happen 2', {
743 '/main.dart': '''
744 class I1 {
745 int x;
746 }
747 class I2 {
748 int y;
749 }
750
751 class I3 implements I1, I2 {
752 int x;
753 int y;
754 }
755
756 class A {
757 final I1 a;
758 }
759
760 class B {
761 final I2 a;
762 }
763
764 class C1 extends A implements B {
765 I3 get a => null;
766 }
767
768 class C2 extends A implements B {
769 /*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/get a => null;
770 }
771 '''
772 });
773
774 testChecker(
775 'infer from RHS only if it wont conflict with overridden fields', {
776 '/main.dart': '''
777 class A {
778 var x;
779 }
780
781 class B extends A {
782 var x = 2;
783 }
784
785 foo() {
786 String y = /*info:DynamicCast*/new B().x;
787 int z = /*info:DynamicCast*/new B().x;
788 }
789 '''
790 });
791
792 testChecker(
793 'infer from RHS only if it wont conflict with overridden fields 2', {
794 '/main.dart': '''
795 class A {
796 final x;
797 }
798
799 class B extends A {
800 final x = 2;
801 }
802
803 foo() {
804 String y = /*severe:StaticTypeError*/new B().x;
805 int z = new B().x;
806 }
807 '''
808 });
809
810 testChecker('infer correctly on multiple variables declared together', {
811 '/main.dart': '''
812 class A {
813 var x, y = 2, z = "hi";
814 }
815
816 class B extends A {
817 var x = 2, y = 3, z, w = 2;
818 }
819
820 foo() {
821 String s;
822 int i;
823
824 s = /*info:DynamicCast*/new B().x;
825 s = /*severe:StaticTypeError*/new B().y;
826 s = new B().z;
827 s = /*severe:StaticTypeError*/new B().w;
828
829 i = /*info:DynamicCast*/new B().x;
830 i = new B().y;
831 i = /*severe:StaticTypeError*/new B().z;
832 i = new B().w;
833 }
834 '''
835 });
836
837 testChecker('infer consts transitively', {
838 '/b.dart': '''
839 const b1 = 2;
840 ''',
841 '/a.dart': '''
842 import 'main.dart';
843 import 'b.dart';
844 const a1 = m2;
845 const a2 = b1;
846 ''',
847 '/main.dart': '''
848 import 'a.dart';
849 const m1 = a1;
850 const m2 = a2;
851
852 foo() {
853 int i;
854 i = m1;
855 }
856 '''
857 });
858
859 testChecker('infer statics transitively', {
860 '/b.dart': '''
861 final b1 = 2;
862 ''',
863 '/a.dart': '''
864 import 'main.dart';
865 import 'b.dart';
866 final a1 = m2;
867 class A {
868 static final a2 = b1;
869 }
870 ''',
871 '/main.dart': '''
872 import 'a.dart';
873 final m1 = a1;
874 final m2 = A.a2;
875
876 foo() {
877 int i;
878 i = m1;
879 }
880 '''
881 });
882
883 testChecker('infer statics transitively 2', {
884 '/main.dart': '''
885 const x1 = 1;
886 final x2 = 1;
887 final y1 = x1;
888 final y2 = x2;
889
890 foo() {
891 int i;
892 i = y1;
893 i = y2;
894 }
895 '''
896 });
897
898 testChecker('infer statics transitively 3', {
899 '/a.dart': '''
900 const a1 = 3;
901 const a2 = 4;
902 class A {
903 a3;
904 }
905 ''',
906 '/main.dart': '''
907 import 'a.dart' show a1, A;
908 import 'a.dart' as p show a2, A;
909 const t1 = 1;
910 const t2 = t1;
911 const t3 = a1;
912 const t4 = p.a2;
913 const t5 = A.a3;
914 const t6 = p.A.a3;
915
916 foo() {
917 int i;
918 i = t1;
919 i = t2;
920 i = t3;
921 i = t4;
922 }
923 '''
924 });
925
926 testChecker('infer statics with method invocations', {
927 '/a.dart': '''
928 m3(String a, String b, [a1,a2]) {}
929 ''',
930 '/main.dart': '''
931 import 'a.dart';
932 class T {
933 static final T foo = m1(m2(m3('', '')));
934 static T m1(String m) { return null; }
935 static String m2(e) { return ''; }
936 }
937
938
939 '''
940 });
941
942 testChecker('downwards inference: miscellaneous', {
943 '/main.dart': '''
944 typedef (T x);
945 class A<T> {
946 Function2<T> x;
947 A(this.x);
948 }
949 void main() {
950 { // Variables, nested literals
951 var x = "hello";
952 var y = 3;
953 void f(List<Map<int, String>> l) {};
954 f(/*info:InferredTypeLiteral*/[{y: x}]);
955 }
956 {
957 int f(int x) {};
958 A<int> a = /*info:InferredTypeAllocation*/new A(f);
959 }
960 }
961 '''
962 });
963
964 group('downwards inference on instance creations', () {
965 String info = 'info:InferredTypeAllocation';
966 String code = '''
967 class A<S, T> {
968 S x;
969 T y;
970 A(this.x, this.y);
971 A.named(this.x, this.y);
972 }
973
974 class B<S, T> extends A<T, S> {
975 B(S y, T x) : super(x, y);
976 B.named(S y, T x) : super.named(x, y);
977 }
978
979 class C<S> extends B<S, S> {
980 C(S a) : super(a, a);
981 C.named(S a) : super.named(a, a);
982 }
983
984 class D<S, T> extends B<T, int> {
985 D(T a) : super(a, 3);
986 D.named(T a) : super.named(a, 3);
987 }
988
989 class E<S, T> extends A<C<S>, T> {
990 E(T a) : super(null, a);
991 }
992
993 class F<S, T> extends A<S, T> {
994 F(S x, T y, {List<S> a, List<T> b}) : super(x, y);
995 F.named(S x, T y, [S a, T b]) : super(a, b);
996 }
997
998 void main() {
999 {
1000 A<int, String> a0 = /*$info*/new A(3, "hello");
1001 A<int, String> a1 = /*$info*/new A.named(3, "hello");
1002 A<int, String> a2 = new A<int, String>(3, "hello");
1003 A<int, String> a3 = new A<int, String>.named(3, "hello");
1004 A<int, String> a4 = /*severe:StaticTypeError*/new A<int, dynamic>(3, " hello");
1005 A<int, String> a5 = /*severe:StaticTypeError*/new A<dynamic, dynamic>. named(3, "hello");
1006 }
1007 {
1008 A<int, String> a0 = /*severe:StaticTypeError*/new A("hello", 3);
1009 A<int, String> a1 = /*severe:StaticTypeError*/new A.named("hello", 3);
1010 }
1011 {
1012 A<int, String> a0 = /*$info*/new B("hello", 3);
1013 A<int, String> a1 = /*$info*/new B.named("hello", 3);
1014 A<int, String> a2 = new B<String, int>("hello", 3);
1015 A<int, String> a3 = new B<String, int>.named("hello", 3);
1016 A<int, String> a4 = /*severe:StaticTypeError*/new B<String, dynamic>(" hello", 3);
1017 A<int, String> a5 = /*severe:StaticTypeError*/new B<dynamic, dynamic>. named("hello", 3);
1018 }
1019 {
1020 A<int, String> a0 = /*severe:StaticTypeError*/new B(3, "hello");
1021 A<int, String> a1 = /*severe:StaticTypeError*/new B.named(3, "hello");
1022 }
1023 {
1024 A<int, int> a0 = /*$info*/new C(3);
1025 A<int, int> a1 = /*$info*/new C.named(3);
1026 A<int, int> a2 = new C<int>(3);
1027 A<int, int> a3 = new C<int>.named(3);
1028 A<int, int> a4 = /*severe:StaticTypeError*/new C<dynamic>(3);
1029 A<int, int> a5 = /*severe:StaticTypeError*/new C<dynamic>.named(3);
1030 }
1031 {
1032 A<int, int> a0 = /*severe:StaticTypeError*/new C("hello");
1033 A<int, int> a1 = /*severe:StaticTypeError*/new C.named("hello");
1034 }
1035 {
1036 A<int, String> a0 = /*$info*/new D("hello");
1037 A<int, String> a1 = /*$info*/new D.named("hello");
1038 A<int, String> a2 = new D<int, String>("hello");
1039 A<int, String> a3 = new D<String, String>.named("hello");
1040 A<int, String> a4 = /*severe:StaticTypeError*/new D<num, dynamic>("hel lo");
1041 A<int, String> a5 = /*severe:StaticTypeError*/new D<dynamic, dynamic>. named("hello");
1042 }
1043 {
1044 A<int, String> a0 = /*severe:StaticTypeError*/new D(3);
1045 A<int, String> a1 = /*severe:StaticTypeError*/new D.named(3);
1046 }
1047 { // Currently we only allow variable constraints. Test that we reject.
1048 A<C<int>, String> a0 = /*severe:StaticTypeError*/new E("hello");
1049 }
1050 { // Check named and optional arguments
1051 A<int, String> a0 = /*$info*/new F(3, "hello", a: [3], b: ["hello"]);
1052 A<int, String> a1 = /*severe:StaticTypeError*/new F(3, "hello", a: ["h ello"], b:[3]);
1053 A<int, String> a2 = /*$info*/new F.named(3, "hello", 3, "hello");
1054 A<int, String> a3 = /*$info*/new F.named(3, "hello");
1055 A<int, String> a4 = /*severe:StaticTypeError*/new F.named(3, "hello", "hello", 3);
1056 A<int, String> a5 = /*severe:StaticTypeError*/new F.named(3, "hello", "hello");
1057 }
1058 }
1059 ''';
1060 testChecker('infer downwards', {'/main.dart': code});
1061 });
1062
1063 group('downwards inference on list literals', () {
1064 String info = "info:InferredTypeLiteral";
1065 String code = '''
1066 void foo([List<String> list1 = /*$info*/const [],
1067 List<String> list2 = /*severe:StaticTypeError*/const [42]]) {
1068 }
1069
1070 void main() {
1071 {
1072 List<int> l0 = /*$info*/[];
1073 List<int> l1 = /*$info*/[3];
1074 List<int> l2 = /*severe:StaticTypeError*/["hello"];
1075 List<int> l3 = /*severe:StaticTypeError*/["hello", 3];
1076 }
1077 {
1078 List<dynamic> l0 = [];
1079 List<dynamic> l1 = [3];
1080 List<dynamic> l2 = ["hello"];
1081 List<dynamic> l3 = ["hello", 3];
1082 }
1083 {
1084 List<int> l0 = /*severe:StaticTypeError*/<num>[];
1085 List<int> l1 = /*severe:StaticTypeError*/<num>[3];
1086 List<int> l2 = /*severe:StaticTypeError*/<num>[/*severe:StaticTypeErro r*/"hello"];
1087 List<int> l3 = /*severe:StaticTypeError*/<num>[/*severe:StaticTypeErro r*/"hello", 3];
1088 }
1089 {
1090 Iterable<int> i0 = /*$info*/[];
1091 Iterable<int> i1 = /*$info*/[3];
1092 Iterable<int> i2 = /*severe:StaticTypeError*/["hello"];
1093 Iterable<int> i3 = /*severe:StaticTypeError*/["hello", 3];
1094 }
1095 {
1096 const List<int> c0 = /*$info*/const [];
1097 const List<int> c1 = /*$info*/const [3];
1098 const List<int> c2 = /*severe:StaticTypeError*/const ["hello"];
1099 const List<int> c3 = /*severe:StaticTypeError*/const ["hello", 3];
1100 }
1101 }
1102 ''';
1103 testChecker('infer downwards', {'/main.dart': code});
1104 });
1105
1106 group('downwards inference on function arguments', () {
1107 String info = "info:InferredTypeLiteral";
1108 String code = '''
1109 void f0(List<int> a) {};
1110 void f1({List<int> a}) {};
1111 void f2(Iterable<int> a) {};
1112 void f3(Iterable<Iterable<int>> a) {};
1113 void f4({Iterable<Iterable<int>> a}) {};
1114 void main() {
1115 f0(/*$info*/[]);
1116 f0(/*$info*/[3]);
1117 f0(/*severe:StaticTypeError*/["hello"]);
1118 f0(/*severe:StaticTypeError*/["hello", 3]);
1119
1120 f1(a: /*$info*/[]);
1121 f1(a: /*$info*/[3]);
1122 f1(a: /*severe:StaticTypeError*/["hello"]);
1123 f1(a: /*severe:StaticTypeError*/["hello", 3]);
1124
1125 f2(/*$info*/[]);
1126 f2(/*$info*/[3]);
1127 f2(/*severe:StaticTypeError*/["hello"]);
1128 f2(/*severe:StaticTypeError*/["hello", 3]);
1129
1130 f3(/*$info*/[]);
1131 f3(/*$info*/[[3]]);
1132 f3(/*severe:StaticTypeError*/[["hello"]]);
1133 f3(/*severe:StaticTypeError*/[["hello"], [3]]);
1134
1135 f4(a: /*$info*/[]);
1136 f4(a: /*$info*/[[3]]);
1137 f4(a: /*severe:StaticTypeError*/[["hello"]]);
1138 f4(a: /*severe:StaticTypeError*/[["hello"], [3]]);
1139 }
1140 ''';
1141 testChecker('infer downwards', {'/main.dart': code});
1142 });
1143
1144 group('downwards inference on map literals', () {
1145 String info = "info:InferredTypeLiteral";
1146 String code = '''
1147 void foo([Map<int, String> m1 = /*$info*/const {1: "hello"},
1148 Map<int, String> m1 = /*severe:StaticTypeError*/const {"hello": "world"}]) {
1149 }
1150 void main() {
1151 {
1152 Map<int, String> l0 = /*$info*/{};
1153 Map<int, String> l1 = /*$info*/{3: "hello"};
1154 Map<int, String> l2 = /*severe:StaticTypeError*/{"hello": "hello"};
1155 Map<int, String> l3 = /*severe:StaticTypeError*/{3: 3};
1156 Map<int, String> l4 = /*severe:StaticTypeError*/{3:"hello", "hello": 3 };
1157 }
1158 {
1159 Map<dynamic, dynamic> l0 = {};
1160 Map<dynamic, dynamic> l1 = {3: "hello"};
1161 Map<dynamic, dynamic> l2 = {"hello": "hello"};
1162 Map<dynamic, dynamic> l3 = {3: 3};
1163 Map<dynamic, dynamic> l4 = {3:"hello", "hello": 3};
1164 }
1165 {
1166 Map<dynamic, String> l0 = /*$info*/{};
1167 Map<dynamic, String> l1 = /*$info*/{3: "hello"};
1168 Map<dynamic, String> l2 = /*$info*/{"hello": "hello"};
1169 Map<dynamic, String> l3 = /*severe:StaticTypeError*/{3: 3};
1170 Map<dynamic, String> l4 = /*severe:StaticTypeError*/{3:"hello", "hello ": 3};
1171 }
1172 {
1173 Map<int, dynamic> l0 = /*$info*/{};
1174 Map<int, dynamic> l1 = /*$info*/{3: "hello"};
1175 Map<int, dynamic> l2 = /*severe:StaticTypeError*/{"hello": "hello"};
1176 Map<int, dynamic> l3 = /*$info*/{3: 3};
1177 Map<int, dynamic> l3 = /*severe:StaticTypeError*/{3:"hello", "hello": 3};
1178 }
1179 {
1180 Map<int, String> l0 = /*severe:StaticTypeError*/<num, dynamic>{};
1181 Map<int, String> l1 = /*severe:StaticTypeError*/<num, dynamic>{3: "hel lo"};
1182 Map<int, String> l3 = /*severe:StaticTypeError*/<num, dynamic>{3: 3};
1183 }
1184 {
1185 const Map<int, String> l0 = /*$info*/const {};
1186 const Map<int, String> l1 = /*$info*/const {3: "hello"};
1187 const Map<int, String> l2 = /*severe:StaticTypeError*/const {"hello": "hello"};
1188 const Map<int, String> l3 = /*severe:StaticTypeError*/const {3: 3};
1189 const Map<int, String> l4 = /*severe:StaticTypeError*/const {3:"hello" , "hello": 3};
1190 }
1191 }
1192 ''';
1193 testChecker('infer downwards', {'/main.dart': code});
1194 });
1195
1196 testChecker('downwards inference on function expressions', {
1197 '/main.dart': '''
1198 typedef T Function2<S, T>(S x);
1199
1200 void main () {
1201 {
1202 Function2<int, String> l0 = (int x) => null;
1203 Function2<int, String> l1 = (int x) => "hello";
1204 Function2<int, String> l2 = /*severe:StaticTypeError*/(String x) => "h ello";
1205 Function2<int, String> l3 = /*severe:StaticTypeError*/(int x) => 3;
1206 Function2<int, String> l4 = /*warning:UninferredClosure should be seve re:StaticTypeError*/(int x) {return 3};
1207 }
1208 {
1209 Function2<int, String> l0 = /*info:InferredTypeClosure*/(x) => null;
1210 Function2<int, String> l1 = /*info:InferredTypeClosure*/(x) => "hello" ;
1211 Function2<int, String> l2 = /*severe:StaticTypeError*/(x) => 3;
1212 Function2<int, String> l3 = /*warning:UninferredClosure should be seve re:StaticTypeError*/(x) {return 3};
1213 }
1214 {
1215 Function2<int, List<String>> l0 = (int x) => null;
1216 Function2<int, List<String>> l1 = /*info:InferredTypeClosure*/(int x) => ["hello"];
1217 Function2<int, List<String>> l2 = /*severe:StaticTypeError*/(String x) => ["hello"];
1218 Function2<int, List<String>> l3 = /*warning:UninferredClosure should b e severe:StaticTypeError*/(int x) => [3];
1219 Function2<int, List<String>> l4 = /*warning:UninferredClosure should b e severe:StaticTypeError*/(int x) {return [3]};
1220 }
1221 {
1222 Function2<int, int> l0 = /*info:InferredTypeClosure*/(x) => x;
1223 Function2<int, int> l1 = /*info:InferredTypeClosure*/(x) => /*info:Dyn amicInvoke should be pass*/x+1;
1224 Function2<int, String> l2 = /*info:InferredTypeClosure should be sever e:StaticTypeError*/(x) => x;
1225 Function2<int, String> l3 = /*info:InferredTypeClosure should be sever e:StaticTypeError*/(x) => /*info:DynamicInvoke should be pass*/x.substring(3);
1226 Function2<String, String> l4 = /*info:InferredTypeClosure*/(x) => /*in fo:DynamicInvoke should be pass*/x.substring(3);
1227 }
1228 }
1229 '''
1230 });
1231
1232 testChecker('inferred initializing formal checks default value', {
1233 '/main.dart': '''
1234 class Foo {
1235 var x = 1;
1236 Foo([this.x = /*severe:StaticTypeError*/"1"]);
1237 }'''
1238 });
1239
1240 group('quasi-generics', () {
1241 testChecker('dart:math min/max', {
1242 '/main.dart': '''
1243 import 'dart:math';
1244
1245 void printInt(int x) => print(x);
1246 void printDouble(double x) => print(x);
1247
1248 num myMax(num x, num y) => max(x, y);
1249
1250 main() {
1251 // Okay if static types match.
1252 printInt(max(1, 2));
1253 printInt(min(1, 2));
1254 printDouble(max(1.0, 2.0));
1255 printDouble(min(1.0, 2.0));
1256
1257 // No help for user-defined functions from num->num->num.
1258 printInt(/*info:DownCastImplicit*/myMax(1, 2));
1259 printInt(myMax(1, 2) as int);
1260
1261 // Mixing int and double means return type is num.
1262 printInt(/*info:DownCastImplicit*/max(1, 2.0));
1263 printInt(/*info:DownCastImplicit*/min(1, 2.0));
1264 printDouble(/*info:DownCastImplicit*/max(1, 2.0));
1265 printDouble(/*info:DownCastImplicit*/min(1, 2.0));
1266
1267 // Types other than int and double are not accepted.
1268 printInt(
1269 /*info:DownCastImplicit*/min(
1270 /*severe:StaticTypeError*/"hi",
1271 /*severe:StaticTypeError*/"there"));
1272 }
1273 '''
1274 });
1275
1276 testChecker('Iterable and Future', {
1277 '/main.dart': '''
1278 import 'dart:async';
1279
1280 Future<int> make(int x) => (/*info:InferredTypeAllocation*/new Future(() => x));
1281
1282 main() {
1283 Iterable<Future<int>> list = <int>[1, 2, 3].map(make);
1284 Future<List<int>> results = Future.wait(list);
1285 Future<String> results2 = results.then((List<int> list)
1286 => list.fold('', (String x, int y) => x + y.toString()));
1287 }
1288 '''
1289 });
1290 });
1291 }
OLDNEW
« no previous file with comments | « test/checker/dart_foobar.dart ('k') | test/checker/self_host_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698