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

Side by Side Diff: packages/analyzer/test/src/task/strong/checker_test.dart

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

Powered by Google App Engine
This is Rietveld 408576698