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

Side by Side Diff: test/checker/checker_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/all_tests.dart ('k') | test/checker/dart_foobar.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 /// General type checking tests
6 library dev_compiler.test.checker_test;
7
8 import 'package:test/test.dart';
9
10 import '../testing.dart';
11
12 void main() {
13 testChecker('ternary operator', {
14 '/main.dart': '''
15 abstract class Comparable<T> {
16 int compareTo(T other);
17 static int compare(Comparable a, Comparable b) => a.compareTo(b);
18 }
19 typedef int Comparator<T>(T a, T b);
20
21 typedef bool _Predicate<T>(T value);
22
23 class SplayTreeMap<K, V> {
24 Comparator<K> _comparator;
25 _Predicate _validKey;
26
27 // Initializing _comparator needs a cast, since K may not always be
28 // Comparable.
29 // Initializing _validKey shouldn't need a cast. Currently
30 // it requires inference to work because of dartbug.com/23381
31 SplayTreeMap([int compare(K key1, K key2),
32 bool isValidKey(potentialKey)]) {
33 : _comparator = /*warning:DownCastComposite*/(compare == null) ? Com parable.compare : compare,
34 _validKey = /*info:InferredType should be pass*/(isValidKey != nul l) ? isValidKey : ((v) => true);
35 _Predicate<Object> _v = /*warning:DownCastComposite*/(isValidKey ! = null) ? isValidKey : ((v) => true);
36 _v = /*info:InferredType should be pass*/(isValidKey != null) ? _v : ((v) => true);
37 }
38 }
39 void main() {
40 Object obj = 42;
41 dynamic dyn = 42;
42 int i = 42;
43
44 // Check the boolean conversion of the condition.
45 print((/*severe:StaticTypeError*/i) ? false : true);
46 print((/*info:DownCastImplicit*/obj) ? false : true);
47 print((/*info:DynamicCast*/dyn) ? false : true);
48 }
49 '''
50 });
51
52 testChecker('if/for/do/while statements use boolean conversion', {
53 '/main.dart': '''
54 main() {
55 dynamic d = 42;
56 Object obj = 42;
57 int i = 42;
58 bool b = false;
59
60 if (b) {}
61 if (/*info:DynamicCast*/dyn) {}
62 if (/*info:DownCastImplicit*/obj) {}
63 if (/*severe:StaticTypeError*/i) {}
64
65 while (b) {}
66 while (/*info:DynamicCast*/dyn) {}
67 while (/*info:DownCastImplicit*/obj) {}
68 while (/*severe:StaticTypeError*/i) {}
69
70 do {} while (b);
71 do {} while (/*info:DynamicCast*/dyn);
72 do {} while (/*info:DownCastImplicit*/obj);
73 do {} while (/*severe:StaticTypeError*/i);
74
75 for (;b;) {}
76 for (;/*info:DynamicCast*/dyn;) {}
77 for (;/*info:DownCastImplicit*/obj;) {}
78 for (;/*severe:StaticTypeError*/i;) {}
79 }
80 '''
81 });
82
83 testChecker('dynamic invocation', {
84 '/main.dart': '''
85
86 class A {
87 dynamic call(dynamic x) => x;
88 }
89 class B extends A {
90 int call(int x) => x;
91 double col(double x) => x;
92 }
93 void main() {
94 {
95 B f = new B();
96 int x;
97 double y;
98 // The analyzer has what I believe is a bug (dartbug.com/23252) which
99 // causes the return type of calls to f to be treated as dynamic.
100 x = /*info:DynamicCast should be pass*/f(3);
101 x = /*severe:StaticTypeError*/f.col(3.0);
102 y = /*info:DynamicCast should be severe:StaticTypeError*/f(3);
103 y = f.col(3.0);
104 f(/*severe:StaticTypeError*/3.0);
105 f.col(/*severe:StaticTypeError*/3);
106 }
107 {
108 Function f = new B();
109 int x;
110 double y;
111 x = /*info:DynamicCast, info:DynamicInvoke*/f(3);
112 x = /*info:DynamicCast, info:DynamicInvoke*/f.col(3.0);
113 y = /*info:DynamicCast, info:DynamicInvoke*/f(3);
114 y = /*info:DynamicCast, info:DynamicInvoke*/f.col(3.0);
115 (/*info:DynamicInvoke*/f(3.0));
116 (/*info:DynamicInvoke*/f.col(3));
117 }
118 {
119 A f = new B();
120 int x;
121 double y;
122 x = /*info:DynamicCast, info:DynamicInvoke*/f(3);
123 y = /*info:DynamicCast, info:DynamicInvoke*/f(3);
124 (/*info:DynamicInvoke*/f(3.0));
125 }
126 }
127 '''
128 });
129
130 testChecker('conversion and dynamic invoke', {
131 '/helper.dart': '''
132 dynamic toString = (int x) => x + 42;
133 dynamic hashCode = "hello";
134 ''',
135 '/main.dart': '''
136 import 'helper.dart' as helper;
137
138 class A {
139 String x = "hello world";
140
141 void baz1(y) => x + /*info:DynamicCast*/y;
142 static baz2(y) => /*info:DynamicInvoke*/y + y;
143 }
144
145 void foo(String str) {
146 print(str);
147 }
148
149 class B {
150 String toString([int arg]) => arg.toString();
151 }
152
153 void bar(a) {
154 foo(/*info:DynamicCast,info:DynamicInvoke*/a.x);
155 }
156
157 baz() => new B();
158
159 typedef DynFun(x);
160 typedef StrFun(String x);
161
162 var bar1 = bar;
163
164 void main() {
165 var a = new A();
166 bar(a);
167 (/*info:DynamicInvoke*/bar1(a));
168 var b = bar;
169 (/*info:DynamicInvoke*/b(a));
170 var f1 = foo;
171 f1("hello");
172 dynamic f2 = foo;
173 (/*info:DynamicInvoke*/f2("hello"));
174 DynFun f3 = foo;
175 (/*info:DynamicInvoke*/f3("hello"));
176 (/*info:DynamicInvoke*/f3(42));
177 StrFun f4 = foo;
178 f4("hello");
179 a.baz1("hello");
180 var b1 = a.baz1;
181 (/*info:DynamicInvoke*/b1("hello"));
182 A.baz2("hello");
183 var b2 = A.baz2;
184 (/*info:DynamicInvoke*/b2("hello"));
185
186 dynamic a1 = new B();
187 (/*info:DynamicInvoke*/a1.x);
188 a1.toString();
189 (/*info:DynamicInvoke*/a1.toString(42));
190 var toStringClosure = a1.toString;
191 (/*info:DynamicInvoke*/a1.toStringClosure());
192 (/*info:DynamicInvoke*/a1.toStringClosure(42));
193 (/*info:DynamicInvoke*/a1.toStringClosure("hello"));
194 a1.hashCode;
195
196 dynamic toString = () => null;
197 (/*info:DynamicInvoke*/toString());
198
199 (/*info:DynamicInvoke*/helper.toString());
200 var toStringClosure2 = helper.toString;
201 (/*info:DynamicInvoke*/toStringClosure2());
202 int hashCode = /*info:DynamicCast*/helper.hashCode;
203
204 baz().toString();
205 baz().hashCode;
206 }
207 '''
208 });
209
210 testChecker('Constructors', {
211 '/main.dart': '''
212 const num z = 25;
213 Object obj = "world";
214
215 class A {
216 int x;
217 String y;
218
219 A(this.x) : this.y = /*severe:StaticTypeError*/42;
220
221 A.c1(p): this.x = /*info:DownCastImplicit*/z, this.y = /*info:DynamicCas t*/p;
222
223 A.c2(this.x, this.y);
224
225 A.c3(/*severe:InvalidParameterDeclaration*/num this.x, String this.y);
226 }
227
228 class B extends A {
229 B() : super(/*severe:StaticTypeError*/"hello");
230
231 B.c2(int x, String y) : super.c2(/*severe:StaticTypeError*/y,
232 /*severe:StaticTypeError*/x);
233
234 B.c3(num x, Object y) : super.c3(x, /*info:DownCastImplicit*/y);
235 }
236
237 void main() {
238 A a = new A.c2(/*info:DownCastImplicit*/z, /*severe:StaticTypeError*/z) ;
239 var b = new B.c2(/*severe:StaticTypeError*/"hello", /*info:DownCastImpl icit*/obj);
240 }
241 '''
242 });
243
244 testChecker('Unbound variable', {
245 '/main.dart': '''
246 void main() {
247 dynamic y = /*pass should be severe:StaticTypeError*/unboundVariable;
248 }
249 '''
250 });
251
252 testChecker('Unbound type name', {
253 '/main.dart': '''
254 void main() {
255 /*pass should be severe:StaticTypeError*/AToB y;
256 }
257 '''
258 });
259
260 testChecker('Ground type subtyping: dynamic is top', {
261 '/main.dart': '''
262
263 class A {}
264 class B extends A {}
265
266 void main() {
267 dynamic y;
268 Object o;
269 int i = 0;
270 double d = 0.0;
271 num n;
272 A a;
273 B b;
274 y = o;
275 y = i;
276 y = d;
277 y = n;
278 y = a;
279 y = b;
280 }
281 '''
282 });
283
284 testChecker('Ground type subtyping: dynamic downcasts', {
285 '/main.dart': '''
286
287 class A {}
288 class B extends A {}
289
290 void main() {
291 dynamic y;
292 Object o;
293 int i = 0;
294 double d = 0.0;
295 num n;
296 A a;
297 B b;
298 o = y;
299 i = /*info:DynamicCast*/y;
300 d = /*info:DynamicCast*/y;
301 n = /*info:DynamicCast*/y;
302 a = /*info:DynamicCast*/y;
303 b = /*info:DynamicCast*/y;
304 }
305 '''
306 });
307
308 testChecker('Ground type subtyping: assigning a class', {
309 '/main.dart': '''
310
311 class A {}
312 class B extends A {}
313
314 void main() {
315 dynamic y;
316 Object o;
317 int i = 0;
318 double d = 0.0;
319 num n;
320 A a;
321 B b;
322 y = a;
323 o = a;
324 i = /*severe:StaticTypeError*/a;
325 d = /*severe:StaticTypeError*/a;
326 n = /*severe:StaticTypeError*/a;
327 a = a;
328 b = /*info:DownCastImplicit*/a;
329 }
330 '''
331 });
332
333 testChecker('Ground type subtyping: assigning a subclass', {
334 '/main.dart': '''
335
336 class A {}
337 class B extends A {}
338 class C extends A {}
339
340 void main() {
341 dynamic y;
342 Object o;
343 int i = 0;
344 double d = 0.0;
345 num n;
346 A a;
347 B b;
348 C c;
349 y = b;
350 o = b;
351 i = /*severe:StaticTypeError*/b;
352 d = /*severe:StaticTypeError*/b;
353 n = /*severe:StaticTypeError*/b;
354 a = b;
355 b = b;
356 c = /*severe:StaticTypeError*/b;
357 }
358 '''
359 });
360
361 testChecker('Ground type subtyping: interfaces', {
362 '/main.dart': '''
363
364 class A {}
365 class B extends A {}
366 class C extends A {}
367 class D extends B implements C {}
368
369 void main() {
370 A top;
371 B left;
372 C right;
373 D bot;
374 {
375 top = top;
376 top = left;
377 top = right;
378 top = bot;
379 }
380 {
381 left = /*info:DownCastImplicit*/top;
382 left = left;
383 left = /*severe:StaticTypeError*/right;
384 left = bot;
385 }
386 {
387 right = /*info:DownCastImplicit*/top;
388 right = /*severe:StaticTypeError*/left;
389 right = right;
390 right = bot;
391 }
392 {
393 bot = /*info:DownCastImplicit*/top;
394 bot = /*info:DownCastImplicit*/left;
395 bot = /*info:DownCastImplicit*/right;
396 bot = bot;
397 }
398 }
399 '''
400 });
401
402 testChecker('Function typing and subtyping: int and object', {
403 '/main.dart': '''
404
405 typedef Object Top(int x); // Top of the lattice
406 typedef int Left(int x); // Left branch
407 typedef int Left2(int x); // Left branch
408 typedef Object Right(Object x); // Right branch
409 typedef int Bot(Object x); // Bottom of the lattice
410
411 Object top(int x) => x;
412 int left(int x) => x;
413 Object right(Object x) => x;
414 int _bot(Object x) => /*info:DownCastImplicit*/x;
415 int bot(Object x) => x as int;
416
417 void main() {
418 { // Check typedef equality
419 Left f = left;
420 Left2 g = f;
421 }
422 {
423 Top f;
424 f = top;
425 f = left;
426 f = right;
427 f = bot;
428 }
429 {
430 Left f;
431 f = /*warning:DownCastComposite*/top;
432 f = left;
433 f = /*warning:DownCastComposite*/right; // Should we reject this?
434 f = bot;
435 }
436 {
437 Right f;
438 f = /*warning:DownCastComposite*/top;
439 f = /*warning:DownCastComposite*/left; // Should we reject this?
440 f = right;
441 f = bot;
442 }
443 {
444 Bot f;
445 f = /*warning:DownCastComposite*/top;
446 f = /*warning:DownCastComposite*/left;
447 f = /*warning:DownCastComposite*/right;
448 f = bot;
449 }
450 }
451 '''
452 });
453
454 testChecker('Function typing and subtyping: classes', {
455 '/main.dart': '''
456
457 class A {}
458 class B extends A {}
459
460 typedef A Top(B x); // Top of the lattice
461 typedef B Left(B x); // Left branch
462 typedef B Left2(B x); // Left branch
463 typedef A Right(A x); // Right branch
464 typedef B Bot(A x); // Bottom of the lattice
465
466 B left(B x) => x;
467 B _bot(A x) => /*info:DownCastImplicit*/x;
468 B bot(A x) => x as B;
469 A top(B x) => x;
470 A right(A x) => x;
471
472 void main() {
473 { // Check typedef equality
474 Left f = left;
475 Left2 g = f;
476 }
477 {
478 Top f;
479 f = top;
480 f = left;
481 f = right;
482 f = bot;
483 }
484 {
485 Left f;
486 f = /*warning:DownCastComposite*/top;
487 f = left;
488 f = /*warning:DownCastComposite*/right; // Should we reject this?
489 f = bot;
490 }
491 {
492 Right f;
493 f = /*warning:DownCastComposite*/top;
494 f = /*warning:DownCastComposite*/left; // Should we reject this?
495 f = right;
496 f = bot;
497 }
498 {
499 Bot f;
500 f = /*warning:DownCastComposite*/top;
501 f = /*warning:DownCastComposite*/left;
502 f = /*warning:DownCastComposite*/right;
503 f = bot;
504 }
505 }
506 '''
507 });
508
509 testChecker('Function typing and subtyping: dynamic', {
510 '/main.dart': '''
511
512 class A {}
513
514 typedef dynamic Top(dynamic x); // Top of the lattice
515 typedef dynamic Left(A x); // Left branch
516 typedef A Right(dynamic x); // Right branch
517 typedef A Bottom(A x); // Bottom of the lattice
518
519 dynamic left(A x) => x;
520 A bot(A x) => x;
521 dynamic top(dynamic x) => x;
522 A right(dynamic x) => /*info:DynamicCast*/x;
523
524 void main() {
525 {
526 Top f;
527 f = top;
528 f = left;
529 f = right;
530 f = bot;
531 }
532 {
533 Left f;
534 f = /*warning:DownCastComposite*/top;
535 f = left;
536 f = /*warning:DownCastComposite*/right;
537 f = bot;
538 }
539 {
540 Right f;
541 f = /*warning:DownCastComposite*/top;
542 f = /*warning:DownCastComposite*/left;
543 f = right;
544 f = bot;
545 }
546 {
547 Bottom f;
548 f = /*warning:DownCastComposite*/top;
549 f = /*warning:DownCastComposite*/left;
550 f = /*warning:DownCastComposite*/right;
551 f = bot;
552 }
553 }
554 '''
555 });
556
557 testChecker('Function typing and subtyping: function literal variance', {
558 '/main.dart': '''
559
560 class A {}
561 class B extends A {}
562
563 typedef T Function2<S, T>(S z);
564
565 A top(B x) => x;
566 B left(B x) => x;
567 A right(A x) => x;
568 B bot(A x) => x as B;
569
570 void main() {
571 {
572 Function2<B, A> f;
573 f = top;
574 f = left;
575 f = right;
576 f = bot;
577 }
578 {
579 Function2<B, B> f;
580 f = /*warning:DownCastComposite*/top;
581 f = left;
582 f = /*warning:DownCastComposite*/right; // Should we reject this?
583 f = bot;
584 }
585 {
586 Function2<A, A> f;
587 f = /*warning:DownCastComposite*/top;
588 f = /*warning:DownCastComposite*/left; // Should we reject this?
589 f = right;
590 f = bot;
591 }
592 {
593 Function2<A, B> f;
594 f = /*warning:DownCastComposite*/top;
595 f = /*warning:DownCastComposite*/left;
596 f = /*warning:DownCastComposite*/right;
597 f = bot;
598 }
599 }
600 '''
601 });
602
603 testChecker('Function typing and subtyping: function variable variance', {
604 '/main.dart': '''
605
606 class A {}
607 class B extends A {}
608
609 typedef T Function2<S, T>(S z);
610
611 void main() {
612 {
613 Function2<B, A> top;
614 Function2<B, B> left;
615 Function2<A, A> right;
616 Function2<A, B> bot;
617
618 top = right;
619 top = bot;
620 top = top;
621 top = left;
622
623 left = /*warning:DownCastComposite*/top;
624 left = left;
625 left = /*warning:DownCastComposite*/right; // Should we reject this?
626 left = bot;
627
628 right = /*warning:DownCastComposite*/top;
629 right = /*warning:DownCastComposite*/left; // Should we reject this?
630 right = right;
631 right = bot;
632
633 bot = /*warning:DownCastComposite*/top;
634 bot = /*warning:DownCastComposite*/left;
635 bot = /*warning:DownCastComposite*/right;
636 bot = bot;
637 }
638 }
639 '''
640 });
641
642 testChecker('Function typing and subtyping: higher order function literals', {
643 '/main.dart': '''
644
645 class A {}
646 class B extends A {}
647
648 typedef T Function2<S, T>(S z);
649
650 typedef A BToA(B x); // Top of the base lattice
651 typedef B AToB(A x); // Bot of the base lattice
652
653 BToA top(AToB f) => f;
654 AToB left(AToB f) => f;
655 BToA right(BToA f) => f;
656 AToB _bot(BToA f) => /*warning:DownCastComposite*/f;
657 AToB bot(BToA f) => f as AToB;
658
659 Function2<B, A> top(AToB f) => f;
660 Function2<A, B> left(AToB f) => f;
661 Function2<B, A> right(BToA f) => f;
662 Function2<A, B> _bot(BToA f) => /*warning:DownCastComposite*/f;
663 Function2<A, B> bot(BToA f) => f as Function2<A, B>;
664
665
666 BToA top(Function2<A, B> f) => f;
667 AToB left(Function2<A, B> f) => f;
668 BToA right(Function2<B, A> f) => f;
669 AToB _bot(Function2<B, A> f) => /*warning:DownCastComposite*/f;
670 AToB bot(Function2<B, A> f) => f as AToB;
671
672 void main() {
673 {
674 Function2<AToB, BToA> f; // Top
675 f = top;
676 f = left;
677 f = right;
678 f = bot;
679 }
680 {
681 Function2<AToB, AToB> f; // Left
682 f = /*warning:DownCastComposite*/top;
683 f = left;
684 f = /*warning:DownCastComposite*/right; // Should we reject this?
685 f = bot;
686 }
687 {
688 Function2<BToA, BToA> f; // Right
689 f = /*warning:DownCastComposite*/top;
690 f = /*warning:DownCastComposite*/left; // Should we reject this?
691 f = right;
692 f = bot;
693 }
694 {
695 Function2<BToA, AToB> f; // Bot
696 f = bot;
697 f = /*warning:DownCastComposite*/left;
698 f = /*warning:DownCastComposite*/top;
699 f = /*warning:DownCastComposite*/left;
700 }
701 }
702 '''
703 });
704
705 testChecker(
706 'Function typing and subtyping: higher order function variables', {
707 '/main.dart': '''
708
709 class A {}
710 class B extends A {}
711
712 typedef T Function2<S, T>(S z);
713
714 void main() {
715 {
716 Function2<Function2<A, B>, Function2<B, A>> top;
717 Function2<Function2<B, A>, Function2<B, A>> right;
718 Function2<Function2<A, B>, Function2<A, B>> left;
719 Function2<Function2<B, A>, Function2<A, B>> bot;
720
721 top = right;
722 top = bot;
723 top = top;
724 top = left;
725
726 left = /*warning:DownCastComposite*/top;
727 left = left;
728 left =
729 /*warning:DownCastComposite should be severe:StaticTypeError*/right;
730 left = bot;
731
732 right = /*warning:DownCastComposite*/top;
733 right =
734 /*warning:DownCastComposite should be severe:StaticTypeError*/left;
735 right = right;
736 right = bot;
737
738 bot = /*warning:DownCastComposite*/top;
739 bot = /*warning:DownCastComposite*/left;
740 bot = /*warning:DownCastComposite*/right;
741 bot = bot;
742 }
743 }
744 '''
745 });
746
747 testChecker('Function typing and subtyping: named and optional parameters', {
748 '/main.dart': '''
749
750 class A {}
751
752 typedef A FR(A x);
753 typedef A FO([A x]);
754 typedef A FN({A x});
755 typedef A FRR(A x, A y);
756 typedef A FRO(A x, [A y]);
757 typedef A FRN(A x, {A n});
758 typedef A FOO([A x, A y]);
759 typedef A FNN({A x, A y});
760 typedef A FNNN({A z, A y, A x});
761
762 void main() {
763 FR r;
764 FO o;
765 FN n;
766 FRR rr;
767 FRO ro;
768 FRN rn;
769 FOO oo;
770 FNN nn;
771 FNNN nnn;
772
773 r = r;
774 r = o;
775 r = /*severe:StaticTypeError*/n;
776 r = /*severe:StaticTypeError*/rr;
777 r = ro;
778 r = rn;
779 r = oo;
780 r = /*severe:StaticTypeError*/nn;
781 r = /*severe:StaticTypeError*/nnn;
782
783 o = /*warning:DownCastComposite*/r;
784 o = o;
785 o = /*severe:StaticTypeError*/n;
786 o = /*severe:StaticTypeError*/rr;
787 o = /*severe:StaticTypeError*/ro;
788 o = /*severe:StaticTypeError*/rn;
789 o = oo;
790 o = /*severe:StaticTypeError*/nn
791 o = /*severe:StaticTypeError*/nnn;
792
793 n = /*severe:StaticTypeError*/r;
794 n = /*severe:StaticTypeError*/o;
795 n = n;
796 n = /*severe:StaticTypeError*/rr;
797 n = /*severe:StaticTypeError*/ro;
798 n = /*severe:StaticTypeError*/rn;
799 n = /*severe:StaticTypeError*/oo;
800 n = nn;
801 n = nnn;
802
803 rr = /*severe:StaticTypeError*/r;
804 rr = /*severe:StaticTypeError*/o;
805 rr = /*severe:StaticTypeError*/n;
806 rr = rr;
807 rr = ro;
808 rr = /*severe:StaticTypeError*/rn;
809 rr = oo;
810 rr = /*severe:StaticTypeError*/nn;
811 rr = /*severe:StaticTypeError*/nnn;
812
813 ro = /*warning:DownCastComposite*/r;
814 ro = /*severe:StaticTypeError*/o;
815 ro = /*severe:StaticTypeError*/n;
816 ro = /*warning:DownCastComposite*/rr;
817 ro = ro;
818 ro = /*severe:StaticTypeError*/rn;
819 ro = oo;
820 ro = /*severe:StaticTypeError*/nn;
821 ro = /*severe:StaticTypeError*/nnn;
822
823 rn = /*warning:DownCastComposite*/r;
824 rn = /*severe:StaticTypeError*/o;
825 rn = /*severe:StaticTypeError*/n;
826 rn = /*severe:StaticTypeError*/rr;
827 rn = /*severe:StaticTypeError*/ro;
828 rn = rn;
829 rn = /*severe:StaticTypeError*/oo;
830 rn = /*severe:StaticTypeError*/nn;
831 rn = /*severe:StaticTypeError*/nnn;
832
833 oo = /*warning:DownCastComposite*/r;
834 oo = /*warning:DownCastComposite*/o;
835 oo = /*severe:StaticTypeError*/n;
836 oo = /*warning:DownCastComposite*/rr;
837 oo = /*warning:DownCastComposite*/ro;
838 oo = /*severe:StaticTypeError*/rn;
839 oo = oo;
840 oo = /*severe:StaticTypeError*/nn;
841 oo = /*severe:StaticTypeError*/nnn;
842
843 nn = /*severe:StaticTypeError*/r;
844 nn = /*severe:StaticTypeError*/o;
845 nn = /*warning:DownCastComposite*/n;
846 nn = /*severe:StaticTypeError*/rr;
847 nn = /*severe:StaticTypeError*/ro;
848 nn = /*severe:StaticTypeError*/rn;
849 nn = /*severe:StaticTypeError*/oo;
850 nn = nn;
851 nn = nnn;
852
853 nnn = /*severe:StaticTypeError*/r;
854 nnn = /*severe:StaticTypeError*/o;
855 nnn = /*warning:DownCastComposite*/n;
856 nnn = /*severe:StaticTypeError*/rr;
857 nnn = /*severe:StaticTypeError*/ro;
858 nnn = /*severe:StaticTypeError*/rn;
859 nnn = /*severe:StaticTypeError*/oo;
860 nnn = /*warning:DownCastComposite*/nn;
861 nnn = nnn;
862 }
863 '''
864 });
865
866 testChecker('Function subtyping: objects with call methods', {
867 '/main.dart': '''
868
869 typedef int I2I(int x);
870 typedef num N2N(num x);
871 class A {
872 int call(int x) => x;
873 }
874 class B {
875 num call(num x) => x;
876 }
877 int i2i(int x) => x;
878 num n2n(num x) => x;
879 void main() {
880 {
881 I2I f;
882 f = new A();
883 f = /*severe:StaticTypeError*/new B();
884 f = i2i;
885 f = /*warning:DownCastComposite*/n2n;
886 f = /*warning:DownCastComposite*/i2i as Object;
887 f = /*warning:DownCastComposite*/n2n as Function;
888 }
889 {
890 N2N f;
891 f = /*severe:StaticTypeError*/new A();
892 f = new B();
893 f = /*warning:DownCastComposite*/i2i;
894 f = n2n;
895 f = /*warning:DownCastComposite*/i2i as Object;
896 f = /*warning:DownCastComposite*/n2n as Function;
897 }
898 {
899 A f;
900 f = new A();
901 f = /*severe:StaticTypeError*/new B();
902 f = /*severe:StaticTypeError*/i2i;
903 f = /*severe:StaticTypeError*/n2n;
904 f = /*info:DownCastImplicit*/i2i as Object;
905 f = /*info:DownCastImplicit*/n2n as Function;
906 }
907 {
908 B f;
909 f = /*severe:StaticTypeError*/new A();
910 f = new B();
911 f = /*severe:StaticTypeError*/i2i;
912 f = /*severe:StaticTypeError*/n2n;
913 f = /*info:DownCastImplicit*/i2i as Object;
914 f = /*info:DownCastImplicit*/n2n as Function;
915 }
916 {
917 Function f;
918 f = new A();
919 f = new B();
920 f = i2i;
921 f = n2n;
922 f = /*info:DownCastImplicit*/i2i as Object;
923 f = (n2n as Function);
924 }
925 }
926 '''
927 });
928
929 testChecker('Function typing and subtyping: void', {
930 '/main.dart': '''
931
932 class A {
933 void bar() => null;
934 void foo() => bar; // allowed
935 }
936 '''
937 });
938
939 testChecker('Relaxed casts', {
940 '/main.dart': '''
941
942 class A {}
943
944 class L<T> {}
945 class M<T> extends L<T> {}
946 // L<dynamic|Object>
947 // / \
948 // M<dynamic|Object> L<A>
949 // \ /
950 // M<A>
951 // In normal Dart, there are additional edges
952 // from M<A> to M<dynamic>
953 // from L<A> to M<dynamic>
954 // from L<A> to L<dynamic>
955 void main() {
956 L lOfDs;
957 L<Object> lOfOs;
958 L<A> lOfAs;
959
960 M mOfDs;
961 M<Object> mOfOs;
962 M<A> mOfAs;
963
964 {
965 lOfDs = mOfDs;
966 lOfDs = mOfOs;
967 lOfDs = mOfAs;
968 lOfDs = lOfDs;
969 lOfDs = lOfOs;
970 lOfDs = lOfAs;
971 }
972 {
973 lOfOs = mOfDs;
974 lOfOs = mOfOs;
975 lOfOs = mOfAs;
976 lOfOs = lOfDs;
977 lOfOs = lOfOs;
978 lOfOs = lOfAs;
979 }
980 {
981 lOfAs = /*warning:DownCastComposite*/mOfDs;
982 lOfAs = /*severe:StaticTypeError*/mOfOs;
983 lOfAs = mOfAs;
984 lOfAs = /*warning:DownCastComposite*/lOfDs;
985 lOfAs = /*warning:DownCastComposite*/lOfOs;
986 lOfAs = lOfAs;
987 }
988 {
989 mOfDs = mOfDs;
990 mOfDs = mOfOs;
991 mOfDs = mOfAs;
992 mOfDs = /*info:DownCastImplicit*/lOfDs;
993 mOfDs = /*info:DownCastImplicit*/lOfOs;
994 mOfDs = /*info:DownCastImplicit*/lOfAs;
995 }
996 {
997 mOfOs = mOfDs;
998 mOfOs = mOfOs;
999 mOfOs = mOfAs;
1000 mOfOs = /*info:DownCastImplicit*/lOfDs;
1001 mOfOs = /*info:DownCastImplicit*/lOfOs;
1002 mOfOs = /*severe:StaticTypeError*/lOfAs;
1003 }
1004 {
1005 mOfAs = /*warning:DownCastComposite*/mOfDs;
1006 mOfAs = /*warning:DownCastComposite*/mOfOs;
1007 mOfAs = mOfAs;
1008 mOfAs = /*warning:DownCastComposite*/lOfDs;
1009 mOfAs = /*warning:DownCastComposite*/lOfOs;
1010 mOfAs = /*warning:DownCastComposite*/lOfAs;
1011 }
1012
1013 }
1014 '''
1015 });
1016
1017 testChecker('Type checking literals', {
1018 '/main.dart': '''
1019 test() {
1020 num n = 3;
1021 int i = 3;
1022 String s = "hello";
1023 {
1024 List<int> l = <int>[i];
1025 l = <int>[/*severe:StaticTypeError*/s];
1026 l = <int>[/*info:DownCastImplicit*/n];
1027 l = <int>[i, /*info:DownCastImplicit*/n, /*severe:StaticTypeError */s];
1028 }
1029 {
1030 List l = [i];
1031 l = [s];
1032 l = [n];
1033 l = [i, n, s];
1034 }
1035 {
1036 Map<String, int> m = <String, int>{s: i};
1037 m = <String, int>{s: /*severe:StaticTypeError*/s};
1038 m = <String, int>{s: /*info:DownCastImplicit*/n};
1039 m = <String, int>{s: i,
1040 s: /*info:DownCastImplicit*/n,
1041 s: /*severe:StaticTypeError*/s};
1042 }
1043 // TODO(leafp): We can't currently test for key errors since the
1044 // error marker binds to the entire entry.
1045 {
1046 Map m = {s: i};
1047 m = {s: s};
1048 m = {s: n};
1049 m = {s: i,
1050 s: n,
1051 s: s};
1052 m = {i: s,
1053 n: s,
1054 s: s};
1055 }
1056 }
1057 '''
1058 });
1059
1060 testChecker('casts in constant contexts', {
1061 '/main.dart': '''
1062 class A {
1063 static const num n = 3.0;
1064 static const int i = /*info:AssignmentCast*/n;
1065 final int fi;
1066 const A(num a) : this.fi = /*info:DownCastImplicit*/a;
1067 }
1068 class B extends A {
1069 const B(Object a) : super(/*info:DownCastImplicit*/a);
1070 }
1071 void foo(Object o) {
1072 var a = const A(/*info:DownCastImplicit*/o);
1073 }
1074 '''
1075 });
1076
1077 testChecker('casts in conditionals', {
1078 '/main.dart': '''
1079 main() {
1080 bool b = true;
1081 num x = b ? 1 : 2.3;
1082 int y = /*info:AssignmentCast*/b ? 1 : 2.3;
1083 String z = !b ? "hello" : null;
1084 z = b ? null : "hello";
1085 }
1086 '''
1087 });
1088
1089 testChecker('redirecting constructor', {
1090 '/main.dart': '''
1091 class A {
1092 A(A x) {}
1093 A.two() : this(/*severe:StaticTypeError*/3);
1094 }
1095 '''
1096 });
1097
1098 testChecker('super constructor', {
1099 '/main.dart': '''
1100 class A { A(A x) {} }
1101 class B extends A {
1102 B() : super(/*severe:StaticTypeError*/3);
1103 }
1104 '''
1105 });
1106
1107 testChecker('field/field override', {
1108 '/main.dart': '''
1109 class A {}
1110 class B extends A {}
1111 class C extends B {}
1112
1113 class Base {
1114 B f1;
1115 B f2;
1116 B f3;
1117 B f4;
1118 }
1119
1120 class Child extends Base {
1121 /*severe:InvalidMethodOverride*/A f1; // invalid for getter
1122 /*severe:InvalidMethodOverride*/C f2; // invalid for setter
1123 var f3;
1124 /*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/dynamic f4;
1125 }
1126 '''
1127 });
1128
1129 testChecker('getter/getter override', {
1130 '/main.dart': '''
1131 class A {}
1132 class B extends A {}
1133 class C extends B {}
1134
1135 abstract class Base {
1136 B get f1;
1137 B get f2;
1138 B get f3;
1139 B get f4;
1140 }
1141
1142 class Child extends Base {
1143 /*severe:InvalidMethodOverride*/A get f1 => null;
1144 C get f2 => null;
1145 get f3 => null;
1146 /*severe:InvalidMethodOverride*/dynamic get f4 => null;
1147 }
1148 '''
1149 });
1150
1151 testChecker('field/getter override', {
1152 '/main.dart': '''
1153 class A {}
1154 class B extends A {}
1155 class C extends B {}
1156
1157 abstract class Base {
1158 B f1;
1159 B f2;
1160 B f3;
1161 B f4;
1162 }
1163
1164 class Child extends Base {
1165 /*severe:InvalidMethodOverride*/A get f1 => null;
1166 C get f2 => null;
1167 get f3 => null;
1168 /*severe:InvalidMethodOverride*/dynamic get f4 => null;
1169 }
1170 '''
1171 });
1172
1173 testChecker('setter/setter override', {
1174 '/main.dart': '''
1175 class A {}
1176 class B extends A {}
1177 class C extends B {}
1178
1179 abstract class Base {
1180 void set f1(B value);
1181 void set f2(B value);
1182 void set f3(B value);
1183 void set f4(B value);
1184 void set f5(B value);
1185 }
1186
1187 class Child extends Base {
1188 void set f1(A value) {}
1189 /*severe:InvalidMethodOverride*/void set f2(C value) {}
1190 void set f3(value) {}
1191 /*severe:InvalidMethodOverride*/void set f4(dynamic value) {}
1192 set f5(B value) {}
1193 }
1194 '''
1195 });
1196
1197 testChecker('field/setter override', {
1198 '/main.dart': '''
1199 class A {}
1200 class B extends A {}
1201 class C extends B {}
1202
1203 class Base {
1204 B f1;
1205 B f2;
1206 B f3;
1207 B f4;
1208 B f5;
1209 }
1210
1211 class Child extends Base {
1212 B get f1 => null;
1213 B get f2 => null;
1214 B get f3 => null;
1215 B get f4 => null;
1216 B get f5 => null;
1217
1218 void set f1(A value) {}
1219 /*severe:InvalidMethodOverride*/void set f2(C value) {}
1220 void set f3(value) {}
1221 /*severe:InvalidMethodOverride*/void set f4(dynamic value) {}
1222 set f5(B value) {}
1223 }
1224 '''
1225 });
1226
1227 testChecker('method override', {
1228 '/main.dart': '''
1229 class A {}
1230 class B extends A {}
1231 class C extends B {}
1232
1233 class Base {
1234 B m1(B a);
1235 B m2(B a);
1236 B m3(B a);
1237 B m4(B a);
1238 B m5(B a);
1239 B m6(B a);
1240 }
1241
1242 class Child extends Base {
1243 /*severe:InvalidMethodOverride*/A m1(A value) {}
1244 /*severe:InvalidMethodOverride*/C m2(C value) {}
1245 /*severe:InvalidMethodOverride*/A m3(C value) {}
1246 C m4(A value) {}
1247 m5(value) {}
1248 /*severe:InvalidMethodOverride*/dynamic m6(dynamic value) {}
1249 }
1250 '''
1251 });
1252
1253 testChecker('unary operators', {
1254 '/main.dart': '''
1255 class A {
1256 A operator ~() {}
1257 A operator +(int x) {}
1258 A operator -(int x) {}
1259 A operator -() {}
1260 }
1261
1262 foo() => new A();
1263
1264 test() {
1265 A a = new A();
1266 var c = foo();
1267
1268 ~a;
1269 (/*info:DynamicInvoke*/~d);
1270
1271 !/*severe:StaticTypeError*/a;
1272 !/*info:DynamicCast*/d;
1273
1274 -a;
1275 (/*info:DynamicInvoke*/-d);
1276
1277 ++a;
1278 --a;
1279 (/*info:DynamicInvoke*/++d);
1280 (/*info:DynamicInvoke*/--d);
1281
1282 a++;
1283 a--;
1284 (/*info:DynamicInvoke*/d++);
1285 (/*info:DynamicInvoke*/d--);
1286 }'''
1287 });
1288
1289 testChecker('binary and index operators', {
1290 '/main.dart': '''
1291 class A {
1292 A operator *(B b) {}
1293 A operator /(B b) {}
1294 A operator ~/(B b) {}
1295 A operator %(B b) {}
1296 A operator +(B b) {}
1297 A operator -(B b) {}
1298 A operator <<(B b) {}
1299 A operator >>(B b) {}
1300 A operator &(B b) {}
1301 A operator ^(B b) {}
1302 A operator |(B b) {}
1303 A operator[](B b) {}
1304 }
1305
1306 class B {
1307 A operator -(B b) {}
1308 }
1309
1310 foo() => new A();
1311
1312 test() {
1313 A a = new A();
1314 B b = new B();
1315 var c = foo();
1316 a = a * b;
1317 a = a * /*info:DynamicCast*/c;
1318 a = a / b;
1319 a = a ~/ b;
1320 a = a % b;
1321 a = a + b;
1322 a = a + /*severe:StaticTypeError*/a;
1323 a = a - b;
1324 b = /*severe:StaticTypeError*/b - b;
1325 a = a << b;
1326 a = a >> b;
1327 a = a & b;
1328 a = a ^ b;
1329 a = a | b;
1330 c = (/*info:DynamicInvoke*/c + b);
1331
1332 String x = 'hello';
1333 int y = 42;
1334 x = x + x;
1335 x = x + /*info:DynamicCast*/c;
1336 x = x + /*severe:StaticTypeError*/y;
1337
1338 bool p = true;
1339 p = p && p;
1340 p = p && /*info:DynamicCast*/c;
1341 p = (/*info:DynamicCast*/c) && p;
1342 p = (/*info:DynamicCast*/c) && /*info:DynamicCast*/c;
1343 p = (/*severe:StaticTypeError*/y) && p;
1344 p = c == y;
1345
1346 a = a[b];
1347 a = a[/*info:DynamicCast*/c];
1348 c = (/*info:DynamicInvoke*/c[b]);
1349 a[/*severe:StaticTypeError*/y];
1350 }
1351 '''
1352 });
1353
1354 testChecker('compound assignments', {
1355 '/main.dart': '''
1356 class A {
1357 A operator *(B b) {}
1358 A operator /(B b) {}
1359 A operator ~/(B b) {}
1360 A operator %(B b) {}
1361 A operator +(B b) {}
1362 A operator -(B b) {}
1363 A operator <<(B b) {}
1364 A operator >>(B b) {}
1365 A operator &(B b) {}
1366 A operator ^(B b) {}
1367 A operator |(B b) {}
1368 D operator [](B index) {}
1369 void operator []=(B index, D value) {}
1370 }
1371
1372 class B {
1373 A operator -(B b) {}
1374 }
1375
1376 class D {
1377 D operator +(D d) {}
1378 }
1379
1380 foo() => new A();
1381
1382 test() {
1383 int x = 0;
1384 x += 5;
1385 (/*severe:StaticTypeError*/x += 3.14);
1386
1387 double y = 0.0;
1388 y += 5;
1389 y += 3.14;
1390
1391 num z = 0;
1392 z += 5;
1393 z += 3.14;
1394
1395 x = /*info:DownCastImplicit*/x + z;
1396 x += /*info:DownCastImplicit*/z;
1397 y = /*info:DownCastImplicit*/y + z;
1398 y += /*info:DownCastImplicit*/z;
1399
1400 dynamic w = 42;
1401 x += /*info:DynamicCast*/w;
1402 y += /*info:DynamicCast*/w;
1403 z += /*info:DynamicCast*/w;
1404
1405 A a = new A();
1406 B b = new B();
1407 var c = foo();
1408 a = a * b;
1409 a *= b;
1410 a *= /*info:DynamicCast*/c;
1411 a /= b;
1412 a ~/= b;
1413 a %= b;
1414 a += b;
1415 a += /*severe:StaticTypeError*/a;
1416 a -= b;
1417 (/*severe:StaticTypeError*/b -= b);
1418 a <<= b;
1419 a >>= b;
1420 a &= b;
1421 a ^= b;
1422 a |= b;
1423 (/*info:DynamicInvoke*/c += b);
1424
1425 var d = new D();
1426 a[b] += d;
1427 a[/*info:DynamicCast*/c] += d;
1428 a[/*severe:StaticTypeError*/z] += d;
1429 a[b] += /*info:DynamicCast*/c;
1430 a[b] += /*severe:StaticTypeError*/z;
1431 (/*info:DynamicInvoke*/(/*info:DynamicInvoke*/c[b]) += d);
1432 }
1433 '''
1434 });
1435
1436 testChecker('super call placement', {
1437 '/main.dart': '''
1438 class Base {
1439 var x;
1440 Base() : x = print('Base.1') { print('Base.2'); }
1441 }
1442
1443 class Derived extends Base {
1444 var y, z;
1445 Derived()
1446 : y = print('Derived.1'),
1447 /*severe:InvalidSuperInvocation*/super(),
1448 z = print('Derived.2') {
1449 print('Derived.3');
1450 }
1451 }
1452
1453 class Valid extends Base {
1454 var y, z;
1455 Valid()
1456 : y = print('Valid.1'),
1457 z = print('Valid.2'),
1458 super() {
1459 print('Valid.3');
1460 }
1461 }
1462
1463 class AlsoValid extends Base {
1464 AlsoValid() : super();
1465 }
1466
1467 main() => new Derived();
1468 '''
1469 });
1470
1471 testChecker('for loop variable', {
1472 '/main.dart': '''
1473 foo() {
1474 for (int i = 0; i < 10; i++) {
1475 i = /*severe:StaticTypeError*/"hi";
1476 }
1477 }
1478 bar() {
1479 for (var i = 0; i < 10; i++) {
1480 int j = i + 1;
1481 }
1482 }
1483 '''
1484 });
1485
1486 group('invalid overrides', () {
1487 testChecker('child override', {
1488 '/main.dart': '''
1489 class A {}
1490 class B {}
1491
1492 class Base {
1493 A f;
1494 }
1495
1496 class T1 extends Base {
1497 /*severe:InvalidMethodOverride*/B get f => null;
1498 }
1499
1500 class T2 extends Base {
1501 /*severe:InvalidMethodOverride*/set f(B b) => null;
1502 }
1503
1504 class T3 extends Base {
1505 /*severe:InvalidMethodOverride*/final B f;
1506 }
1507 class T4 extends Base {
1508 // two: one for the getter one for the setter.
1509 /*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/B f;
1510 }
1511 '''
1512 });
1513
1514 testChecker('child override 2', {
1515 '/main.dart': '''
1516 class A {}
1517 class B {}
1518
1519 class Base {
1520 m(A a) {}
1521 }
1522
1523 class Test extends Base {
1524 /*severe:InvalidMethodOverride*/m(B a) {}
1525 }
1526 '''
1527 });
1528 testChecker('grandchild override', {
1529 '/main.dart': '''
1530 class A {}
1531 class B {}
1532
1533 class Grandparent {
1534 m(A a) {}
1535 }
1536 class Parent extends Grandparent {
1537 }
1538
1539 class Test extends Parent {
1540 /*severe:InvalidMethodOverride*/m(B a) {}
1541 }
1542 '''
1543 });
1544
1545 testChecker('double override', {
1546 '/main.dart': '''
1547 class A {}
1548 class B {}
1549
1550 class Grandparent {
1551 m(A a) {}
1552 }
1553 class Parent extends Grandparent {
1554 m(A a) {}
1555 }
1556
1557 class Test extends Parent {
1558 // Reported only once
1559 /*severe:InvalidMethodOverride*/m(B a) {}
1560 }
1561 '''
1562 });
1563
1564 testChecker('double override 2', {
1565 '/main.dart': '''
1566 class A {}
1567 class B {}
1568
1569 class Grandparent {
1570 m(A a) {}
1571 }
1572 class Parent extends Grandparent {
1573 /*severe:InvalidMethodOverride*/m(B a) {}
1574 }
1575
1576 class Test extends Parent {
1577 m(B a) {}
1578 }
1579 '''
1580 });
1581
1582 testChecker('mixin override to base', {
1583 '/main.dart': '''
1584 class A {}
1585 class B {}
1586
1587 class Base {
1588 m(A a) {}
1589 }
1590
1591 class M1 {
1592 m(B a) {}
1593 }
1594
1595 class M2 {}
1596
1597 class T1 extends Base with /*severe:InvalidMethodOverride*/M1 {}
1598 class T2 extends Base with /*severe:InvalidMethodOverride*/M1, M2 {}
1599 class T3 extends Base with M2, /*severe:InvalidMethodOverride*/M1 {}
1600 '''
1601 });
1602
1603 testChecker('mixin override to mixin', {
1604 '/main.dart': '''
1605 class A {}
1606 class B {}
1607
1608 class Base {
1609 }
1610
1611 class M1 {
1612 m(B a) {}
1613 }
1614
1615 class M2 {
1616 m(A a) {}
1617 }
1618
1619 class T1 extends Base with M1, /*severe:InvalidMethodOverride*/M2 {}
1620 '''
1621 });
1622
1623 // This is a regression test for a bug in an earlier implementation were
1624 // names were hiding errors if the first mixin override looked correct,
1625 // but subsequent ones did not.
1626 testChecker('no duplicate mixin override', {
1627 '/main.dart': '''
1628 class A {}
1629 class B {}
1630
1631 class Base {
1632 m(A a) {}
1633 }
1634
1635 class M1 {
1636 m(A a) {}
1637 }
1638
1639 class M2 {
1640 m(B a) {}
1641 }
1642
1643 class M3 {
1644 m(B a) {}
1645 }
1646
1647 class T1 extends Base
1648 with M1, /*severe:InvalidMethodOverride*/M2, M3 {}
1649 '''
1650 });
1651
1652 testChecker('class override of interface', {
1653 '/main.dart': '''
1654 class A {}
1655 class B {}
1656
1657 abstract class I {
1658 m(A a);
1659 }
1660
1661 class T1 implements I {
1662 /*severe:InvalidMethodOverride*/m(B a) {}
1663 }
1664 '''
1665 });
1666
1667 testChecker('base class override to child interface', {
1668 '/main.dart': '''
1669 class A {}
1670 class B {}
1671
1672 abstract class I {
1673 m(A a);
1674 }
1675
1676 class Base {
1677 m(B a) {}
1678 }
1679
1680
1681 class T1 /*severe:InvalidMethodOverride*/extends Base implements I {
1682 }
1683 '''
1684 });
1685
1686 testChecker('mixin override of interface', {
1687 '/main.dart': '''
1688 class A {}
1689 class B {}
1690
1691 abstract class I {
1692 m(A a);
1693 }
1694
1695 class M {
1696 m(B a) {}
1697 }
1698
1699 class T1 extends Object with /*severe:InvalidMethodOverride*/M
1700 implements I {}
1701 '''
1702 });
1703
1704 // This is a case were it is incorrect to say that the base class
1705 // incorrectly overrides the interface.
1706 testChecker(
1707 'no errors if subclass correctly overrides base and interface', {
1708 '/main.dart': '''
1709 class A {}
1710 class B {}
1711
1712 class Base {
1713 m(A a) {}
1714 }
1715
1716 class I1 {
1717 m(B a) {}
1718 }
1719
1720 class T1 /*severe:InvalidMethodOverride*/extends Base
1721 implements I1 {}
1722
1723 class T2 extends Base implements I1 {
1724 /*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/m(a ) {}
1725 }
1726
1727 class T3 extends Object with /*severe:InvalidMethodOverride*/Base
1728 implements I1 {}
1729
1730 class T4 extends Object with Base implements I1 {
1731 /*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/m(a ) {}
1732 }
1733 '''
1734 });
1735 });
1736
1737 group('class override of grand interface', () {
1738 testChecker('interface of interface of child', {
1739 '/main.dart': '''
1740 class A {}
1741 class B {}
1742
1743 abstract class I1 {
1744 m(A a);
1745 }
1746 abstract class I2 implements I1 {}
1747
1748 class T1 implements I2 {
1749 /*severe:InvalidMethodOverride*/m(B a) {}
1750 }
1751 '''
1752 });
1753 testChecker('superclass of interface of child', {
1754 '/main.dart': '''
1755 class A {}
1756 class B {}
1757
1758 abstract class I1 {
1759 m(A a);
1760 }
1761 abstract class I2 extends I1 {}
1762
1763 class T1 implements I2 {
1764 /*severe:InvalidMethodOverride*/m(B a) {}
1765 }
1766 '''
1767 });
1768 testChecker('mixin of interface of child', {
1769 '/main.dart': '''
1770 class A {}
1771 class B {}
1772
1773 abstract class M1 {
1774 m(A a);
1775 }
1776 abstract class I2 extends Object with M1 {}
1777
1778 class T1 implements I2 {
1779 /*severe:InvalidMethodOverride*/m(B a) {}
1780 }
1781 '''
1782 });
1783 testChecker('interface of abstract superclass', {
1784 '/main.dart': '''
1785 class A {}
1786 class B {}
1787
1788 abstract class I1 {
1789 m(A a);
1790 }
1791 abstract class Base implements I1 {}
1792
1793 class T1 extends Base {
1794 /*severe:InvalidMethodOverride*/m(B a) {}
1795 }
1796 '''
1797 });
1798 testChecker('interface of concrete superclass', {
1799 '/main.dart': '''
1800 class A {}
1801 class B {}
1802
1803 abstract class I1 {
1804 m(A a);
1805 }
1806
1807 // See issue #25
1808 /*pass should be warning:AnalyzerError*/class Base implements I1 {
1809 }
1810
1811 class T1 extends Base {
1812 // not reported technically because if the class is concrete,
1813 // it should implement all its interfaces and hence it is
1814 // sufficient to check overrides against it.
1815 m(B a) {}
1816 }
1817 '''
1818 });
1819 });
1820
1821 group('mixin override of grand interface', () {
1822 testChecker('interface of interface of child', {
1823 '/main.dart': '''
1824 class A {}
1825 class B {}
1826
1827 abstract class I1 {
1828 m(A a);
1829 }
1830 abstract class I2 implements I1 {}
1831
1832 class M {
1833 m(B a) {}
1834 }
1835
1836 class T1 extends Object with /*severe:InvalidMethodOverride*/M
1837 implements I2 {
1838 }
1839 '''
1840 });
1841 testChecker('superclass of interface of child', {
1842 '/main.dart': '''
1843 class A {}
1844 class B {}
1845
1846 abstract class I1 {
1847 m(A a);
1848 }
1849 abstract class I2 extends I1 {}
1850
1851 class M {
1852 m(B a) {}
1853 }
1854
1855 class T1 extends Object with /*severe:InvalidMethodOverride*/M
1856 implements I2 {
1857 }
1858 '''
1859 });
1860 testChecker('mixin of interface of child', {
1861 '/main.dart': '''
1862 class A {}
1863 class B {}
1864
1865 abstract class M1 {
1866 m(A a);
1867 }
1868 abstract class I2 extends Object with M1 {}
1869
1870 class M {
1871 m(B a) {}
1872 }
1873
1874 class T1 extends Object with /*severe:InvalidMethodOverride*/M
1875 implements I2 {
1876 }
1877 '''
1878 });
1879 testChecker('interface of abstract superclass', {
1880 '/main.dart': '''
1881 class A {}
1882 class B {}
1883
1884 abstract class I1 {
1885 m(A a);
1886 }
1887 abstract class Base implements I1 {}
1888
1889 class M {
1890 m(B a) {}
1891 }
1892
1893 class T1 extends Base with /*severe:InvalidMethodOverride*/M {
1894 }
1895 '''
1896 });
1897 testChecker('interface of concrete superclass', {
1898 '/main.dart': '''
1899 class A {}
1900 class B {}
1901
1902 abstract class I1 {
1903 m(A a);
1904 }
1905
1906 // See issue #25
1907 /*pass should be warning:AnalyzerError*/class Base implements I1 {
1908 }
1909
1910 class M {
1911 m(B a) {}
1912 }
1913
1914 class T1 extends Base with M {
1915 }
1916 '''
1917 });
1918 });
1919
1920 group('superclass override of grand interface', () {
1921 testChecker('interface of interface of child', {
1922 '/main.dart': '''
1923 class A {}
1924 class B {}
1925
1926 abstract class I1 {
1927 m(A a);
1928 }
1929 abstract class I2 implements I1 {}
1930
1931 class Base {
1932 m(B a) {}
1933 }
1934
1935 class T1 /*severe:InvalidMethodOverride*/extends Base
1936 implements I2 {
1937 }
1938 '''
1939 });
1940 testChecker('superclass of interface of child', {
1941 '/main.dart': '''
1942 class A {}
1943 class B {}
1944
1945 abstract class I1 {
1946 m(A a);
1947 }
1948 abstract class I2 extends I1 {}
1949
1950 class Base {
1951 m(B a) {}
1952 }
1953
1954 class T1 /*severe:InvalidMethodOverride*/extends Base
1955 implements I2 {
1956 }
1957 '''
1958 });
1959 testChecker('mixin of interface of child', {
1960 '/main.dart': '''
1961 class A {}
1962 class B {}
1963
1964 abstract class M1 {
1965 m(A a);
1966 }
1967 abstract class I2 extends Object with M1 {}
1968
1969 class Base {
1970 m(B a) {}
1971 }
1972
1973 class T1 /*severe:InvalidMethodOverride*/extends Base
1974 implements I2 {
1975 }
1976 '''
1977 });
1978 testChecker('interface of abstract superclass', {
1979 '/main.dart': '''
1980 class A {}
1981 class B {}
1982
1983 abstract class I1 {
1984 m(A a);
1985 }
1986
1987 abstract class Base implements I1 {
1988 /*severe:InvalidMethodOverride*/m(B a) {}
1989 }
1990
1991 class T1 extends Base {
1992 // we consider the base class incomplete because it is
1993 // abstract, so we report the error here too.
1994 // TODO(sigmund): consider tracking overrides in a fine-grain
1995 // manner, then this and the double-overrides would not be
1996 // reported.
1997 /*severe:InvalidMethodOverride*/m(B a) {}
1998 }
1999 '''
2000 });
2001 testChecker('interface of concrete superclass', {
2002 '/main.dart': '''
2003 class A {}
2004 class B {}
2005
2006 abstract class I1 {
2007 m(A a);
2008 }
2009
2010 class Base implements I1 {
2011 /*severe:InvalidMethodOverride*/m(B a) {}
2012 }
2013
2014 class T1 extends Base {
2015 m(B a) {}
2016 }
2017 '''
2018 });
2019 });
2020
2021 group('no duplicate reports from overriding interfaces', () {
2022 testChecker('type overrides same method in multiple interfaces', {
2023 '/main.dart': '''
2024 class A {}
2025 class B {}
2026
2027 abstract class I1 {
2028 m(A a);
2029 }
2030 abstract class I2 implements I1 {
2031 m(A a);
2032 }
2033
2034 class Base {
2035 }
2036
2037 class T1 implements I2 {
2038 /*severe:InvalidMethodOverride*/m(B a) {}
2039 }
2040 '''
2041 });
2042
2043 testChecker('type and base type override same method in interface', {
2044 '/main.dart': '''
2045 class A {}
2046 class B {}
2047
2048 abstract class I1 {
2049 m(A a);
2050 }
2051
2052 class Base {
2053 m(B a);
2054 }
2055
2056 // Note: no error reported in `extends Base` to avoid duplicating
2057 // the error in T1.
2058 class T1 extends Base implements I1 {
2059 /*severe:InvalidMethodOverride*/m(B a) {}
2060 }
2061
2062 // If there is no error in the class, we do report the error at
2063 // the base class:
2064 class T2 /*severe:InvalidMethodOverride*/extends Base
2065 implements I1 {
2066 }
2067 '''
2068 });
2069
2070 testChecker('type and mixin override same method in interface', {
2071 '/main.dart': '''
2072 class A {}
2073 class B {}
2074
2075 abstract class I1 {
2076 m(A a);
2077 }
2078
2079 class M {
2080 m(B a);
2081 }
2082
2083 class T1 extends Object with M implements I1 {
2084 /*severe:InvalidMethodOverride*/m(B a) {}
2085 }
2086
2087 class T2 extends Object with /*severe:InvalidMethodOverride*/M
2088 implements I1 {
2089 }
2090 '''
2091 });
2092
2093 testChecker('two grand types override same method in interface', {
2094 '/main.dart': '''
2095 class A {}
2096 class B {}
2097
2098 abstract class I1 {
2099 m(A a);
2100 }
2101
2102 class Grandparent {
2103 m(B a) {}
2104 }
2105
2106 class Parent1 extends Grandparent {
2107 m(B a) {}
2108 }
2109 class Parent2 extends Grandparent {
2110 }
2111
2112 // Note: otherwise both errors would be reported on this line
2113 class T1 /*severe:InvalidMethodOverride*/extends Parent1
2114 implements I1 {
2115 }
2116 class T2 /*severe:InvalidMethodOverride*/extends Parent2
2117 implements I1 {
2118 }
2119 '''
2120 });
2121
2122 testChecker('two mixins override same method in interface', {
2123 '/main.dart': '''
2124 class A {}
2125 class B {}
2126
2127 abstract class I1 {
2128 m(A a);
2129 }
2130
2131 class M1 {
2132 m(B a) {}
2133 }
2134
2135 class M2 {
2136 m(B a) {}
2137 }
2138
2139 // Here we want to report both, because the error location is
2140 // different.
2141 // TODO(sigmund): should we merge these as well?
2142 class T1 extends Object
2143 with /*severe:InvalidMethodOverride*/M1
2144 with /*severe:InvalidMethodOverride*/M2
2145 implements I1 {
2146 }
2147 '''
2148 });
2149
2150 testChecker('base type and mixin override same method in interface', {
2151 '/main.dart': '''
2152 class A {}
2153 class B {}
2154
2155 abstract class I1 {
2156 m(A a);
2157 }
2158
2159 class Base {
2160 m(B a) {}
2161 }
2162
2163 class M {
2164 m(B a) {}
2165 }
2166
2167 // Here we want to report both, because the error location is
2168 // different.
2169 // TODO(sigmund): should we merge these as well?
2170 class T1 /*severe:InvalidMethodOverride*/extends Base
2171 with /*severe:InvalidMethodOverride*/M
2172 implements I1 {
2173 }
2174 '''
2175 });
2176 });
2177
2178 testChecker('invalid runtime checks', {
2179 '/main.dart': '''
2180 typedef int I2I(int x);
2181 typedef int D2I(x);
2182 typedef int II2I(int x, int y);
2183 typedef int DI2I(x, int y);
2184 typedef int ID2I(int x, y);
2185 typedef int DD2I(x, y);
2186
2187 typedef I2D(int x);
2188 typedef D2D(x);
2189 typedef II2D(int x, int y);
2190 typedef DI2D(x, int y);
2191 typedef ID2D(int x, y);
2192 typedef DD2D(x, y);
2193
2194 int foo(int x) => x;
2195 int bar(int x, int y) => x + y;
2196
2197 void main() {
2198 bool b;
2199 b = /*info:NonGroundTypeCheckInfo*/foo is I2I;
2200 b = /*info:NonGroundTypeCheckInfo*/foo is D2I;
2201 b = /*info:NonGroundTypeCheckInfo*/foo is I2D;
2202 b = foo is D2D;
2203
2204 b = /*info:NonGroundTypeCheckInfo*/bar is II2I;
2205 b = /*info:NonGroundTypeCheckInfo*/bar is DI2I;
2206 b = /*info:NonGroundTypeCheckInfo*/bar is ID2I;
2207 b = /*info:NonGroundTypeCheckInfo*/bar is II2D;
2208 b = /*info:NonGroundTypeCheckInfo*/bar is DD2I;
2209 b = /*info:NonGroundTypeCheckInfo*/bar is DI2D;
2210 b = /*info:NonGroundTypeCheckInfo*/bar is ID2D;
2211 b = bar is DD2D;
2212
2213 // For as, the validity of checks is deferred to runtime.
2214 Function f;
2215 f = foo as I2I;
2216 f = foo as D2I;
2217 f = foo as I2D;
2218 f = foo as D2D;
2219
2220 f = bar as II2I;
2221 f = bar as DI2I;
2222 f = bar as ID2I;
2223 f = bar as II2D;
2224 f = bar as DD2I;
2225 f = bar as DI2D;
2226 f = bar as ID2D;
2227 f = bar as DD2D;
2228 }
2229 '''
2230 });
2231
2232 testChecker('custom URL mappings', {
2233 '/main.dart': '''
2234 import 'dart:foobar' show Baz;
2235 main() {
2236 print(Baz.quux);
2237 }'''
2238 }, customUrlMappings: {
2239 'dart:foobar': '$testDirectory/checker/dart_foobar.dart'
2240 });
2241
2242 group('function modifiers', () {
2243 testChecker('async', {
2244 '/main.dart': '''
2245 import 'dart:async';
2246 import 'dart:math' show Random;
2247
2248 dynamic x;
2249
2250 foo1() async => x;
2251 Future foo2() async => x;
2252 Future<int> foo3() async => (/*info:DynamicCast*/x);
2253 Future<int> foo4() async => (/*severe:StaticTypeError*/new Future<int>.v alue(/*info:DynamicCast*/x));
2254
2255 bar1() async { return x; }
2256 Future bar2() async { return x; }
2257 Future<int> bar3() async { return (/*info:DynamicCast*/x); }
2258 Future<int> bar4() async { return (/*severe:StaticTypeError*/new Future< int>.value(/*info:DynamicCast*/x)); }
2259
2260 int y;
2261 Future<int> z;
2262
2263 void baz() async {
2264 int a = /*info:DynamicCast*/await x;
2265 int b = await y;
2266 int c = await z;
2267 String d = /*severe:StaticTypeError*/await z;
2268 }
2269
2270 Future<bool> get issue_264 async {
2271 await 42;
2272 if (new Random().nextBool()) {
2273 return true;
2274 } else {
2275 return /*severe:StaticTypeError*/new Future<bool>.value(false);
2276 }
2277 }
2278 '''
2279 });
2280
2281 testChecker('async*', {
2282 '/main.dart': '''
2283 import 'dart:async';
2284
2285 dynamic x;
2286
2287 bar1() async* { yield x; }
2288 Stream bar2() async* { yield x; }
2289 Stream<int> bar3() async* { yield (/*info:DynamicCast*/x); }
2290 Stream<int> bar4() async* { yield (/*severe:StaticTypeError*/new Stream< int>()); }
2291
2292 baz1() async* { yield* (/*info:DynamicCast*/x); }
2293 Stream baz2() async* { yield* (/*info:DynamicCast*/x); }
2294 Stream<int> baz3() async* { yield* (/*warning:DownCastComposite*/x); }
2295 Stream<int> baz4() async* { yield* new Stream<int>(); }
2296 Stream<int> baz5() async* { yield* (/*info:InferredTypeAllocation*/new S tream()); }
2297 '''
2298 });
2299
2300 testChecker('sync*', {
2301 '/main.dart': '''
2302 import 'dart:async';
2303
2304 dynamic x;
2305
2306 bar1() sync* { yield x; }
2307 Iterable bar2() sync* { yield x; }
2308 Iterable<int> bar3() sync* { yield (/*info:DynamicCast*/x); }
2309 Iterable<int> bar4() sync* { yield (/*severe:StaticTypeError*/new Iterab le<int>()); }
2310
2311 baz1() sync* { yield* (/*info:DynamicCast*/x); }
2312 Iterable baz2() sync* { yield* (/*info:DynamicCast*/x); }
2313 Iterable<int> baz3() sync* { yield* (/*warning:DownCastComposite*/x); }
2314 Iterable<int> baz4() sync* { yield* new Iterable<int>(); }
2315 Iterable<int> baz5() sync* { yield* (/*info:InferredTypeAllocation*/new Iterable()); }
2316 '''
2317 });
2318 });
2319 }
OLDNEW
« no previous file with comments | « test/all_tests.dart ('k') | test/checker/dart_foobar.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698