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

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

Issue 2990843002: Removed fixed dependencies (Closed)
Patch Set: Created 3 years, 4 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
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 // TODO(jmesserly): this file needs to be refactored, it's a port from 5 library analyzer.test.src.task.strong.checker_test;
6 // package:dev_compiler's tests 6
7 /// General type checking tests 7 import 'package:test_reflective_loader/test_reflective_loader.dart';
8 library test.src.task.strong.checker_test;
9
10 import 'package:unittest/unittest.dart';
11 8
12 import 'strong_test_helper.dart'; 9 import 'strong_test_helper.dart';
13 10
14 void main() { 11 void main() {
15 testChecker('ternary operator', { 12 initStrongModeTests();
16 '/main.dart': ''' 13 defineReflectiveTests(CheckerTest);
17 abstract class Comparable<T> { 14 }
18 int compareTo(T other); 15
19 static int compare(Comparable a, Comparable b) => a.compareTo(b); 16 @reflectiveTest
20 } 17 class CheckerTest {
21 typedef int Comparator<T>(T a, T b); 18 void test_awaitForInCastsStreamElementToVariable() {
22 19 checkFile('''
23 typedef bool _Predicate<T>(T value); 20 import 'dart:async';
24 21 main() async {
25 class SplayTreeMap<K, V> { 22 // Don't choke if sequence is not stream.
26 Comparator<K> _comparator; 23 await for (var i in /*error:FOR_IN_OF_INVALID_TYPE*/1234) {}
27 _Predicate _validKey; 24
28 25 // Dynamic cast.
29 // Initializing _comparator needs a cast, since K may not always be 26 await for (String /*info:DYNAMIC_CAST*/s in new Stream<dynamic>()) {}
30 // Comparable. 27
31 // Initializing _validKey shouldn't need a cast. Currently 28 // Identity cast.
32 // it requires inference to work because of dartbug.com/23381 29 await for (String s in new Stream<String>()) {}
33 SplayTreeMap([int compare(K key1, K key2), 30
34 bool isValidKey(potentialKey)]) { 31 // Untyped.
35 : _comparator = /*warning:DownCastComposite*/(compare == null) ? Com parable.compare : compare, 32 await for (var s in new Stream<String>()) {}
36 _validKey = /*info:InferredType should be pass*/(isValidKey != nul l) ? isValidKey : ((v) => true); 33
37 _Predicate<Object> _v = /*warning:DownCastComposite*/(isValidKey ! = null) ? isValidKey : ((v) => true); 34 // Downcast.
38 _v = /*info:InferredType should be pass*/(isValidKey != null) ? _v : ((v) => true); 35 await for (int /*info:DOWN_CAST_IMPLICIT*/i in new Stream<num>()) {}
39 } 36 }
40 } 37 ''');
41 void main() { 38 }
42 Object obj = 42; 39
43 dynamic dyn = 42; 40 void test_awaitForInCastsSupertypeSequenceToStream() {
44 int i = 42; 41 checkFile('''
45 42 main() async {
46 // Check the boolean conversion of the condition. 43 dynamic d;
47 print((/*severe:StaticTypeError*/i) ? false : true); 44 await for (var i in /*info:DYNAMIC_CAST*/d) {}
48 print((/*info:DownCastImplicit*/obj) ? false : true); 45
49 print((/*info:DynamicCast*/dyn) ? false : true); 46 Object o;
50 } 47 await for (var i in /*info:DOWN_CAST_IMPLICIT*/o) {}
51 ''' 48 }
52 }); 49 ''');
53 50 }
54 testChecker('if/for/do/while statements use boolean conversion', { 51
55 '/main.dart': ''' 52 void test_binaryAndIndexOperators() {
56 main() { 53 checkFile('''
57 dynamic d = 42; 54 class A {
58 Object obj = 42; 55 A operator *(B b) => null;
59 int i = 42; 56 A operator /(B b) => null;
60 bool b = false; 57 A operator ~/(B b) => null;
61 58 A operator %(B b) => null;
62 if (b) {} 59 A operator +(B b) => null;
63 if (/*info:DynamicCast*/dyn) {} 60 A operator -(B b) => null;
64 if (/*info:DownCastImplicit*/obj) {} 61 A operator <<(B b) => null;
65 if (/*severe:StaticTypeError*/i) {} 62 A operator >>(B b) => null;
66 63 A operator &(B b) => null;
67 while (b) {} 64 A operator ^(B b) => null;
68 while (/*info:DynamicCast*/dyn) {} 65 A operator |(B b) => null;
69 while (/*info:DownCastImplicit*/obj) {} 66 A operator[](B b) => null;
70 while (/*severe:StaticTypeError*/i) {} 67 }
71 68
72 do {} while (b); 69 class B {
73 do {} while (/*info:DynamicCast*/dyn); 70 A operator -(B b) => null;
74 do {} while (/*info:DownCastImplicit*/obj); 71 }
75 do {} while (/*severe:StaticTypeError*/i); 72
76 73 foo() => new A();
77 for (;b;) {} 74
78 for (;/*info:DynamicCast*/dyn;) {} 75 test() {
79 for (;/*info:DownCastImplicit*/obj;) {} 76 A a = new A();
80 for (;/*severe:StaticTypeError*/i;) {} 77 B b = new B();
81 } 78 var c = foo();
82 ''' 79 a = a * b;
83 }); 80 a = a * /*info:DYNAMIC_CAST*/c;
84 81 a = a / b;
85 testChecker('dynamic invocation', { 82 a = a ~/ b;
86 '/main.dart': ''' 83 a = a % b;
87 84 a = a + b;
88 class A { 85 a = a + /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/a;
89 dynamic call(dynamic x) => x; 86 a = a - b;
90 } 87 b = /*error:INVALID_ASSIGNMENT*/b - b;
91 class B extends A { 88 a = a << b;
92 int call(int x) => x; 89 a = a >> b;
93 double col(double x) => x; 90 a = a & b;
94 } 91 a = a ^ b;
95 void main() { 92 a = a | b;
96 { 93 c = (/*info:DYNAMIC_INVOKE*/c + b);
97 B f = new B(); 94
98 int x; 95 String x = 'hello';
99 double y; 96 int y = 42;
100 // The analyzer has what I believe is a bug (dartbug.com/23252) which 97 x = x + x;
101 // causes the return type of calls to f to be treated as dynamic. 98 x = x + /*info:DYNAMIC_CAST*/c;
102 x = /*info:DynamicCast should be pass*/f(3); 99 x = x + /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/y;
103 x = /*severe:StaticTypeError*/f.col(3.0); 100
104 y = /*info:DynamicCast should be severe:StaticTypeError*/f(3); 101 bool p = true;
105 y = f.col(3.0); 102 p = p && p;
106 f(/*severe:StaticTypeError*/3.0); 103 p = p && /*info:DYNAMIC_CAST*/c;
107 f.col(/*severe:StaticTypeError*/3); 104 p = (/*info:DYNAMIC_CAST*/c) && p;
108 } 105 p = (/*info:DYNAMIC_CAST*/c) && /*info:DYNAMIC_CAST*/c;
109 { 106 p = /*error:NON_BOOL_OPERAND*/y && p;
110 Function f = new B(); 107 p = c == y;
111 int x; 108
112 double y; 109 a = a[b];
113 x = /*info:DynamicCast, info:DynamicInvoke*/f(3); 110 a = a[/*info:DYNAMIC_CAST*/c];
114 x = /*info:DynamicCast, info:DynamicInvoke*/f.col(3.0); 111 c = (/*info:DYNAMIC_INVOKE*/c[b]);
115 y = /*info:DynamicCast, info:DynamicInvoke*/f(3); 112 a[/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/y];
116 y = /*info:DynamicCast, info:DynamicInvoke*/f.col(3.0); 113 }
117 (/*info:DynamicInvoke*/f(3.0)); 114 ''');
118 (/*info:DynamicInvoke*/f.col(3)); 115 }
119 } 116
120 { 117 void test_callMethodOnFunctions() {
121 A f = new B(); 118 checkFile(r'''
122 int x; 119 void f(int x) => print(x);
123 double y; 120 main() {
124 x = /*info:DynamicCast, info:DynamicInvoke*/f(3); 121 f.call(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/'hi');
125 y = /*info:DynamicCast, info:DynamicInvoke*/f(3); 122 }
126 (/*info:DynamicInvoke*/f(3.0)); 123 ''');
127 } 124 }
128 } 125
129 ''' 126 void test_castsInConditions() {
130 }); 127 checkFile('''
131 128 main() {
132 testChecker('conversion and dynamic invoke', { 129 bool b = true;
133 '/helper.dart': ''' 130 num x = b ? 1 : 2.3;
134 dynamic toString = (int x) => x + 42; 131 int y = /*info:ASSIGNMENT_CAST*/b ? 1 : 2.3;
135 dynamic hashCode = "hello"; 132 String z = !b ? "hello" : null;
136 ''', 133 z = b ? null : "hello";
137 '/main.dart': ''' 134 }
138 import 'helper.dart' as helper; 135 ''');
139 136 }
140 class A { 137
141 String x = "hello world"; 138 void test_castsInConstantContexts() {
142 139 checkFile('''
143 void baz1(y) => x + /*info:DynamicCast*/y; 140 class A {
144 static baz2(y) => /*info:DynamicInvoke*/y + y; 141 static const num n = 3.0;
145 } 142 // The severe error is from constant evaluation where we know the
146 143 // concrete type.
147 void foo(String str) { 144 static const int /*error:VARIABLE_TYPE_MISMATCH*/i = /*info:ASSIGNMENT_CAST*/n ;
148 print(str); 145 final int fi;
149 } 146 const A(num a) : this.fi = /*info:DOWN_CAST_IMPLICIT*/a;
150 147 }
151 class B { 148 class B extends A {
152 String toString([int arg]) => arg.toString(); 149 const B(Object a) : super(/*info:DOWN_CAST_IMPLICIT*/a);
153 } 150 }
154 151 void foo(Object o) {
155 void bar(a) { 152 var a = const A(/*info:DOWN_CAST_IMPLICIT, error:CONST_WITH_NON_CONSTANT_ARGUM ENT, error:INVALID_CONSTANT*/o);
156 foo(/*info:DynamicCast,info:DynamicInvoke*/a.x); 153 }
157 } 154 ''');
158 155 }
159 baz() => new B(); 156
160 157 void test_classOverrideOfGrandInterface_interfaceOfAbstractSuperclass() {
161 typedef DynFun(x); 158 checkFile('''
162 typedef StrFun(String x); 159 class A {}
163 160 class B {}
164 var bar1 = bar; 161
165 162 abstract class I1 {
166 void main() { 163 m(A a);
167 var a = new A(); 164 }
168 bar(a); 165 abstract class Base implements I1 {}
169 (/*info:DynamicInvoke*/bar1(a)); 166
170 var b = bar; 167 class T1 extends Base {
171 (/*info:DynamicInvoke*/b(a)); 168 /*error:INVALID_METHOD_OVERRIDE*/m(B a) {}
172 var f1 = foo; 169 }
173 f1("hello"); 170 ''');
174 dynamic f2 = foo; 171 }
175 (/*info:DynamicInvoke*/f2("hello")); 172
176 DynFun f3 = foo; 173 void test_classOverrideOfGrandInterface_interfaceOfConcreteSuperclass() {
177 (/*info:DynamicInvoke*/f3("hello")); 174 checkFile('''
178 (/*info:DynamicInvoke*/f3(42)); 175 class A {}
179 StrFun f4 = foo; 176 class B {}
180 f4("hello"); 177
181 a.baz1("hello"); 178 abstract class I1 {
182 var b1 = a.baz1; 179 m(A a);
183 (/*info:DynamicInvoke*/b1("hello")); 180 }
184 A.baz2("hello"); 181
185 var b2 = A.baz2; 182 class /*error:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/Base
186 (/*info:DynamicInvoke*/b2("hello")); 183 implements I1 {}
187 184
188 dynamic a1 = new B(); 185 class T1 extends Base {
189 (/*info:DynamicInvoke*/a1.x); 186 // not reported technically because if the class is concrete,
190 a1.toString(); 187 // it should implement all its interfaces and hence it is
191 (/*info:DynamicInvoke*/a1.toString(42)); 188 // sufficient to check overrides against it.
192 var toStringClosure = a1.toString; 189 m(B a) {}
193 (/*info:DynamicInvoke*/a1.toStringClosure()); 190 }
194 (/*info:DynamicInvoke*/a1.toStringClosure(42)); 191 ''');
195 (/*info:DynamicInvoke*/a1.toStringClosure("hello")); 192 }
196 a1.hashCode; 193
197 194 void test_classOverrideOfGrandInterface_interfaceOfInterfaceOfChild() {
198 dynamic toString = () => null; 195 checkFile('''
199 (/*info:DynamicInvoke*/toString()); 196 class A {}
200 197 class B {}
201 (/*info:DynamicInvoke*/helper.toString()); 198
202 var toStringClosure2 = helper.toString; 199 abstract class I1 {
203 (/*info:DynamicInvoke*/toStringClosure2()); 200 m(A a);
204 int hashCode = /*info:DynamicCast*/helper.hashCode; 201 }
205 202 abstract class I2 implements I1 {}
206 baz().toString(); 203
207 baz().hashCode; 204 class T1 implements I2 {
208 } 205 /*error:INVALID_METHOD_OVERRIDE*/m(B a) {}
209 ''' 206 }
210 }); 207 ''');
211 208 }
212 testChecker('Constructors', { 209
213 '/main.dart': ''' 210 void test_classOverrideOfGrandInterface_mixinOfInterfaceOfChild() {
214 const num z = 25; 211 checkFile('''
215 Object obj = "world"; 212 class A {}
216 213 class B {}
217 class A { 214
218 int x; 215 abstract class M1 {
219 String y; 216 m(A a);
220 217 }
221 A(this.x) : this.y = /*severe:StaticTypeError*/42; 218 abstract class I2 extends Object with M1 {}
222 219
223 A.c1(p): this.x = /*info:DownCastImplicit*/z, this.y = /*info:DynamicCas t*/p; 220 class T1 implements I2 {
224 221 /*error:INVALID_METHOD_OVERRIDE*/m(B a) {}
225 A.c2(this.x, this.y); 222 }
226 223 ''');
227 A.c3(/*severe:InvalidParameterDeclaration*/num this.x, String this.y); 224 }
228 } 225
229 226 void test_classOverrideOfGrandInterface_superclassOfInterfaceOfChild() {
230 class B extends A { 227 checkFile('''
231 B() : super(/*severe:StaticTypeError*/"hello"); 228 class A {}
232 229 class B {}
233 B.c2(int x, String y) : super.c2(/*severe:StaticTypeError*/y, 230
234 /*severe:StaticTypeError*/x); 231 abstract class I1 {
235 232 m(A a);
236 B.c3(num x, Object y) : super.c3(x, /*info:DownCastImplicit*/y); 233 }
237 } 234 abstract class I2 extends I1 {}
238 235
239 void main() { 236 class T1 implements I2 {
240 A a = new A.c2(/*info:DownCastImplicit*/z, /*severe:StaticTypeError*/z) ; 237 /*error:INVALID_METHOD_OVERRIDE*/m(B a) {}
241 var b = new B.c2(/*severe:StaticTypeError*/"hello", /*info:DownCastImpl icit*/obj); 238 }
242 } 239 ''');
243 ''' 240 }
244 }); 241
245 242 void test_compoundAssignments() {
246 testChecker('Unbound variable', { 243 checkFile('''
247 '/main.dart': ''' 244 class A {
248 void main() { 245 A operator *(B b) => null;
249 dynamic y = /*pass should be severe:StaticTypeError*/unboundVariable; 246 A operator /(B b) => null;
250 } 247 A operator ~/(B b) => null;
251 ''' 248 A operator %(B b) => null;
252 }); 249 A operator +(B b) => null;
253 250 A operator -(B b) => null;
254 testChecker('Unbound type name', { 251 A operator <<(B b) => null;
255 '/main.dart': ''' 252 A operator >>(B b) => null;
256 void main() { 253 A operator &(B b) => null;
257 /*pass should be severe:StaticTypeError*/AToB y; 254 A operator ^(B b) => null;
258 } 255 A operator |(B b) => null;
259 ''' 256 D operator [](B index) => null;
260 }); 257 void operator []=(B index, D value) => null;
261 258 }
262 testChecker('Ground type subtyping: dynamic is top', { 259
263 '/main.dart': ''' 260 class B {
264 261 A operator -(B b) => null;
265 class A {} 262 }
266 class B extends A {} 263
267 264 class D {
268 void main() { 265 D operator +(D d) => null;
269 dynamic y; 266 }
270 Object o; 267
271 int i = 0; 268 class SubA extends A {}
272 double d = 0.0; 269 class SubSubA extends SubA {}
273 num n; 270
274 A a; 271 foo() => new A();
275 B b; 272
276 y = o; 273 test() {
277 y = i; 274 int x = 0;
278 y = d; 275 x += 5;
279 y = n; 276 x += /*error:INVALID_ASSIGNMENT*/3.14;
280 y = a; 277
281 y = b; 278 double y = 0.0;
282 } 279 y += 5;
283 ''' 280 y += 3.14;
284 }); 281
285 282 num z = 0;
286 testChecker('Ground type subtyping: dynamic downcasts', { 283 z += 5;
287 '/main.dart': ''' 284 z += 3.14;
288 285
289 class A {} 286 x = /*info:DOWN_CAST_IMPLICIT*/x + z;
290 class B extends A {} 287 /*info:DOWN_CAST_IMPLICIT_ASSIGN*/x += z;
291 288 y = y + z;
292 void main() { 289 y += z;
293 dynamic y; 290
294 Object o; 291 dynamic w = 42;
295 int i = 0; 292 /*info:DOWN_CAST_IMPLICIT_ASSIGN*/x += /*info:DYNAMIC_CAST*/w;
296 double d = 0.0; 293 y += /*info:DYNAMIC_CAST*/w;
297 num n; 294 z += /*info:DYNAMIC_CAST*/w;
298 A a; 295
299 B b; 296 A a = new A();
300 o = y; 297 B b = new B();
301 i = /*info:DynamicCast*/y; 298 var c = foo();
302 d = /*info:DynamicCast*/y; 299 a = a * b;
303 n = /*info:DynamicCast*/y; 300 a *= b;
304 a = /*info:DynamicCast*/y; 301 a *= /*info:DYNAMIC_CAST*/c;
305 b = /*info:DynamicCast*/y; 302 a /= b;
306 } 303 a ~/= b;
307 ''' 304 a %= b;
308 }); 305 a += b;
309 306 a += /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/a;
310 testChecker('Ground type subtyping: assigning a class', { 307 a -= b;
311 '/main.dart': ''' 308 b -= /*error:INVALID_ASSIGNMENT*/b;
312 309 a <<= b;
313 class A {} 310 a >>= b;
314 class B extends A {} 311 a &= b;
315 312 a ^= b;
316 void main() { 313 a |= b;
317 dynamic y; 314 /*info:DYNAMIC_INVOKE*/c += b;
318 Object o; 315
319 int i = 0; 316 SubA sa;
320 double d = 0.0; 317 /*info:DOWN_CAST_IMPLICIT_ASSIGN*/sa += b;
321 num n; 318 SubSubA ssa = /*info:ASSIGNMENT_CAST,info:DOWN_CAST_IMPLICIT_ASSIGN*/sa += b;
322 A a; 319
323 B b; 320 var d = new D();
324 y = a; 321 a[b] += d;
325 o = a; 322 a[/*info:DYNAMIC_CAST*/c] += d;
326 i = /*severe:StaticTypeError*/a; 323 a[/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/z] += d;
327 d = /*severe:StaticTypeError*/a; 324 a[b] += /*info:DYNAMIC_CAST*/c;
328 n = /*severe:StaticTypeError*/a; 325 a[b] += /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/z;
329 a = a; 326 /*info:DYNAMIC_INVOKE,info:DYNAMIC_INVOKE*/c[b] += d;
330 b = /*info:DownCastImplicit*/a; 327 }
331 } 328 ''');
332 ''' 329 }
333 }); 330
334 331 void test_constantGenericTypeArg_explict() {
335 testChecker('Ground type subtyping: assigning a subclass', { 332 // Regression test for https://github.com/dart-lang/sdk/issues/26141
336 '/main.dart': ''' 333 checkFile('''
337 334 abstract class Equality<R> {}
338 class A {} 335 abstract class EqualityBase<R> implements Equality<R> {
339 class B extends A {} 336 final C<R> c = const C<R>();
340 class C extends A {} 337 const EqualityBase();
341 338 }
342 void main() { 339 class DefaultEquality<S> extends EqualityBase<S> {
343 dynamic y; 340 const DefaultEquality();
344 Object o; 341 }
345 int i = 0; 342 class SetEquality<T> implements Equality<T> {
346 double d = 0.0; 343 final Equality<T> field = const DefaultEquality<T>();
347 num n; 344 const SetEquality([Equality<T> inner = const DefaultEquality<T>()]);
348 A a; 345 }
349 B b; 346 class C<Q> {
350 C c; 347 final List<Q> list = const <Q>[];
351 y = b; 348 final Map<Q, Iterable<Q>> m = const <Q, Iterable<Q>>{};
352 o = b; 349 const C();
353 i = /*severe:StaticTypeError*/b; 350 }
354 d = /*severe:StaticTypeError*/b; 351 main() {
355 n = /*severe:StaticTypeError*/b; 352 const SetEquality<String>();
356 a = b; 353 }
357 b = b; 354 ''');
358 c = /*severe:StaticTypeError*/b; 355 }
359 } 356
360 ''' 357 void test_constantGenericTypeArg_infer() {
361 }); 358 // Regression test for https://github.com/dart-lang/sdk/issues/26141
362 359 checkFile('''
363 testChecker('Ground type subtyping: interfaces', { 360 abstract class Equality<Q> {}
364 '/main.dart': ''' 361 abstract class EqualityBase<R> implements Equality<R> {
365 362 final C<R> c = /*info:INFERRED_TYPE_ALLOCATION*/const C();
366 class A {} 363 const EqualityBase();
367 class B extends A {} 364 }
368 class C extends A {} 365 class DefaultEquality<S> extends EqualityBase<S> {
369 class D extends B implements C {} 366 const DefaultEquality();
370 367 }
371 void main() { 368 class SetEquality<T> implements Equality<T> {
372 A top; 369 final Equality<T> field = const DefaultEquality();
373 B left; 370 const SetEquality([Equality<T> inner = const DefaultEquality()]);
374 C right; 371 }
375 D bot; 372 class C<Q> {
376 { 373 final List<Q> list = /*info:INFERRED_TYPE_LITERAL*/const [];
377 top = top; 374 final Map<Q, Iterable<Q>> m = /*info:INFERRED_TYPE_LITERAL*/const {};
378 top = left; 375 const C();
379 top = right; 376 }
380 top = bot; 377 main() {
381 } 378 const SetEquality<String>();
382 { 379 }
383 left = /*info:DownCastImplicit*/top; 380 ''');
384 left = left; 381 }
385 left = /*severe:StaticTypeError*/right; 382
386 left = bot; 383 void test_compoundAssignment_returnsDynamic() {
387 } 384 checkFile(r'''
388 { 385 class Foo {
389 right = /*info:DownCastImplicit*/top; 386 operator +(other) => null;
390 right = /*severe:StaticTypeError*/left; 387 }
391 right = right; 388
392 right = bot; 389 main() {
393 } 390 var foo = new Foo();
394 { 391 foo = /*info:DYNAMIC_CAST*/foo + 1;
395 bot = /*info:DownCastImplicit*/top; 392 /*info:DYNAMIC_CAST*/foo += 1;
396 bot = /*info:DownCastImplicit*/left; 393 }
397 bot = /*info:DownCastImplicit*/right; 394 ''');
398 bot = bot; 395 }
399 } 396
400 } 397 void test_constructorInvalid() {
401 ''' 398 // Regression test for https://github.com/dart-lang/sdk/issues/26695
402 }); 399 checkFile('''
403 400 class A {
404 testChecker('Function typing and subtyping: int and object', { 401 B({ /*error:FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR*/this.test: 1.0 }) {}
405 '/main.dart': ''' 402 final double test = 0.0;
406 403 }
407 typedef Object Top(int x); // Top of the lattice 404 ''');
408 typedef int Left(int x); // Left branch 405 }
409 typedef int Left2(int x); // Left branch 406
410 typedef Object Right(Object x); // Right branch 407 void test_constructors() {
411 typedef int Bot(Object x); // Bottom of the lattice 408 checkFile('''
412 409 const num z = 25;
413 Object top(int x) => x; 410 Object obj = "world";
414 int left(int x) => x; 411
415 Object right(Object x) => x; 412 class A {
416 int _bot(Object x) => /*info:DownCastImplicit*/x; 413 int x;
417 int bot(Object x) => x as int; 414 String y;
418 415
419 void main() { 416 A(this.x) : this.y = /*error:FIELD_INITIALIZER_NOT_ASSIGNABLE*/42;
420 { // Check typedef equality 417
421 Left f = left; 418 A.c1(p): this.x = /*info:DOWN_CAST_IMPLICIT*/z, this.y = /*info:DYNAMIC_CAST*/ p;
422 Left2 g = f; 419
423 } 420 A.c2(this.x, this.y);
424 { 421
425 Top f; 422 A.c3(/*error:INVALID_PARAMETER_DECLARATION*/num this.x, String this.y);
426 f = top; 423 }
427 f = left; 424
428 f = right; 425 class B extends A {
429 f = bot; 426 B() : super(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello");
430 } 427
431 { 428 B.c2(int x, String y) : super.c2(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/y,
432 Left f; 429 /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/x);
433 f = /*warning:DownCastComposite*/top; 430
434 f = left; 431 B.c3(num x, Object y) : super.c3(x, /*info:DOWN_CAST_IMPLICIT*/y);
435 f = /*warning:DownCastComposite*/right; // Should we reject this? 432 }
436 f = bot; 433
437 } 434 void main() {
438 { 435 A a = new A.c2(/*info:DOWN_CAST_IMPLICIT*/z, /*error:ARGUMENT_TYPE_NOT_ASSIGN ABLE*/z);
439 Right f; 436 var b = new B.c2(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello", /*info:DOWN_C AST_IMPLICIT*/obj);
440 f = /*warning:DownCastComposite*/top; 437 }
441 f = /*warning:DownCastComposite*/left; // Should we reject this? 438 ''');
442 f = right; 439 }
443 f = bot; 440
444 } 441 void test_conversionAndDynamicInvoke() {
445 { 442 addFile(
446 Bot f; 443 '''
447 f = /*warning:DownCastComposite*/top; 444 dynamic toString = (int x) => x + 42;
448 f = /*warning:DownCastComposite*/left; 445 dynamic hashCode = "hello";
449 f = /*warning:DownCastComposite*/right; 446 ''',
450 f = bot; 447 name: '/helper.dart');
451 } 448 checkFile('''
452 } 449 import 'helper.dart' as helper;
453 ''' 450
454 }); 451 class A {
455 452 String x = "hello world";
456 testChecker('Function typing and subtyping: classes', { 453
457 '/main.dart': ''' 454 void baz1(y) { x + /*info:DYNAMIC_CAST*/y; }
458 455 static baz2(y) => /*info:DYNAMIC_INVOKE*/y + y;
459 class A {} 456 }
460 class B extends A {} 457
461 458 void foo(String str) {
462 typedef A Top(B x); // Top of the lattice 459 print(str);
463 typedef B Left(B x); // Left branch 460 }
464 typedef B Left2(B x); // Left branch 461
465 typedef A Right(A x); // Right branch 462 class B {
466 typedef B Bot(A x); // Bottom of the lattice 463 String toString([int arg]) => arg.toString();
467 464 }
468 B left(B x) => x; 465
469 B _bot(A x) => /*info:DownCastImplicit*/x; 466 void bar(a) {
470 B bot(A x) => x as B; 467 foo(/*info:DYNAMIC_CAST,info:DYNAMIC_INVOKE*/a.x);
471 A top(B x) => x; 468 }
472 A right(A x) => x; 469
473 470 baz() => new B();
474 void main() { 471
475 { // Check typedef equality 472 typedef DynFun(x);
476 Left f = left; 473 typedef StrFun(String x);
477 Left2 g = f; 474
478 } 475 var bar1 = bar;
479 { 476
480 Top f; 477 void main() {
481 f = top; 478 var a = new A();
482 f = left; 479 bar(a);
483 f = right; 480 (/*info:DYNAMIC_INVOKE*/bar1(a));
484 f = bot; 481 var b = bar;
485 } 482 (/*info:DYNAMIC_INVOKE*/b(a));
486 { 483 var f1 = foo;
487 Left f; 484 f1("hello");
488 f = /*warning:DownCastComposite*/top; 485 dynamic f2 = foo;
489 f = left; 486 (/*info:DYNAMIC_INVOKE*/f2("hello"));
490 f = /*warning:DownCastComposite*/right; // Should we reject this? 487 DynFun f3 = foo;
491 f = bot; 488 (/*info:DYNAMIC_INVOKE*/f3("hello"));
492 } 489 (/*info:DYNAMIC_INVOKE*/f3(42));
493 { 490 StrFun f4 = foo;
494 Right f; 491 f4("hello");
495 f = /*warning:DownCastComposite*/top; 492 a.baz1("hello");
496 f = /*warning:DownCastComposite*/left; // Should we reject this? 493 var b1 = a.baz1;
497 f = right; 494 (/*info:DYNAMIC_INVOKE*/b1("hello"));
498 f = bot; 495 A.baz2("hello");
499 } 496 var b2 = A.baz2;
500 { 497 (/*info:DYNAMIC_INVOKE*/b2("hello"));
501 Bot f; 498
502 f = /*warning:DownCastComposite*/top; 499 dynamic a1 = new B();
503 f = /*warning:DownCastComposite*/left; 500 (/*info:DYNAMIC_INVOKE*/a1.x);
504 f = /*warning:DownCastComposite*/right; 501 a1.toString();
505 f = bot; 502 (/*info:DYNAMIC_INVOKE*/a1.toString(42));
506 } 503 var toStringClosure = a1.toString;
507 } 504 (/*info:DYNAMIC_INVOKE*/a1.toStringClosure());
508 ''' 505 (/*info:DYNAMIC_INVOKE*/a1.toStringClosure(42));
509 }); 506 (/*info:DYNAMIC_INVOKE*/a1.toStringClosure("hello"));
510 507 a1.hashCode;
511 testChecker('Function typing and subtyping: dynamic', { 508
512 '/main.dart': ''' 509 dynamic toString = () => null;
513 510 (/*info:DYNAMIC_INVOKE*/toString());
514 class A {} 511
515 512 (/*info:DYNAMIC_INVOKE*/helper.toString());
516 typedef dynamic Top(dynamic x); // Top of the lattice 513 var toStringClosure2 = helper.toString;
517 typedef dynamic Left(A x); // Left branch 514 (/*info:DYNAMIC_INVOKE*/toStringClosure2());
518 typedef A Right(dynamic x); // Right branch 515 int hashCode = /*info:DYNAMIC_CAST*/helper.hashCode;
519 typedef A Bottom(A x); // Bottom of the lattice 516
520 517 baz().toString();
521 dynamic left(A x) => x; 518 baz().hashCode;
522 A bot(A x) => x; 519 }
523 dynamic top(dynamic x) => x; 520 ''');
524 A right(dynamic x) => /*info:DynamicCast*/x; 521 }
525 522
526 void main() { 523 void test_covariantOverride() {
527 { 524 _addMetaLibrary();
528 Top f; 525 checkFile(r'''
529 f = top; 526 import 'meta.dart';
530 f = left; 527 class C {
531 f = right; 528 num f(num x) => x;
532 f = bot; 529 }
533 } 530 class D extends C {
534 { 531 int f(@checked int x) => x;
535 Left f; 532 }
536 f = /*warning:DownCastComposite*/top; 533 class E extends D {
537 f = left; 534 int f(Object x) => /*info:DOWN_CAST_IMPLICIT*/x;
538 f = /*warning:DownCastComposite*/right; 535 }
539 f = bot; 536 class F extends E {
540 } 537 int f(@checked int x) => x;
541 { 538 }
542 Right f; 539 class G extends E implements D {}
543 f = /*warning:DownCastComposite*/top; 540
544 f = /*warning:DownCastComposite*/left; 541 class D_error extends C {
545 f = right; 542 /*error:INVALID_METHOD_OVERRIDE*/int f(int x) => x;
546 f = bot; 543 }
547 } 544 class E_error extends D {
548 { 545 /*error:INVALID_METHOD_OVERRIDE*/int f(@checked double x) => 0;
549 Bottom f; 546 }
550 f = /*warning:DownCastComposite*/top; 547 class F_error extends E {
551 f = /*warning:DownCastComposite*/left; 548 /*error:INVALID_METHOD_OVERRIDE*/int f(@checked double x) => 0;
552 f = /*warning:DownCastComposite*/right; 549 }
553 f = bot; 550 class G_error extends E implements D {
554 } 551 /*error:INVALID_METHOD_OVERRIDE*/int f(@checked double x) => 0;
555 } 552 }
556 ''' 553 ''');
557 }); 554 }
558 555
559 testChecker('Function typing and subtyping: function literal variance', { 556 void test_covariantOverride_fields() {
560 '/main.dart': ''' 557 _addMetaLibrary();
561 558 checkFile(r'''
562 class A {} 559 import 'meta.dart';
563 class B extends A {} 560 class A {
564 561 get foo => '';
565 typedef T Function2<S, T>(S z); 562 set foo(_) {}
566 563 }
567 A top(B x) => x; 564
568 B left(B x) => x; 565 class B extends A {
569 A right(A x) => x; 566 @checked num foo;
570 B bot(A x) => x as B; 567 }
571 568 class C extends A {
572 void main() { 569 @checked @virtual num foo;
573 { 570 }
574 Function2<B, A> f; 571 class D extends C {
575 f = top; 572 @virtual int foo;
576 f = left; 573 }
577 f = right; 574 class E extends D {
578 f = bot; 575 @virtual /*error:INVALID_METHOD_OVERRIDE*/num foo;
579 } 576 }
580 { 577 ''');
581 Function2<B, B> f; 578 }
582 f = /*warning:DownCastComposite*/top; 579
583 f = left; 580 void test_covariantOverride_leastUpperBound() {
584 f = /*warning:DownCastComposite*/right; // Should we reject this? 581 _addMetaLibrary();
585 f = bot; 582 checkFile(r'''
586 } 583 import "meta.dart";
587 { 584 abstract class Top {}
588 Function2<A, A> f; 585 abstract class Left implements Top {}
589 f = /*warning:DownCastComposite*/top; 586 abstract class Right implements Top {}
590 f = /*warning:DownCastComposite*/left; // Should we reject this? 587 abstract class Bottom implements Left, Right {}
591 f = right; 588
592 f = bot; 589 abstract class TakesLeft {
593 } 590 m(Left x);
594 { 591 }
595 Function2<A, B> f; 592 abstract class TakesRight {
596 f = /*warning:DownCastComposite*/top; 593 m(Right x);
597 f = /*warning:DownCastComposite*/left; 594 }
598 f = /*warning:DownCastComposite*/right; 595 abstract class TakesTop implements TakesLeft, TakesRight {
599 f = bot; 596 m(Top x); // works today
600 } 597 }
601 } 598 abstract class TakesBottom implements TakesLeft, TakesRight {
602 ''' 599 // LUB(Left, Right) == Top, so this is an implicit cast from Top to Bottom.
603 }); 600 m(@checked Bottom x);
604 601 }
605 testChecker('Function typing and subtyping: function variable variance', { 602 ''');
606 '/main.dart': ''' 603 }
607 604
608 class A {} 605 void test_covariantOverride_markerIsInherited() {
609 class B extends A {} 606 _addMetaLibrary();
610 607 checkFile(r'''
611 typedef T Function2<S, T>(S z); 608 import 'meta.dart';
612 609 class C {
613 void main() { 610 num f(@checked num x) => x;
614 { 611 }
615 Function2<B, A> top; 612 class D extends C {
616 Function2<B, B> left; 613 int f(int x) => x;
617 Function2<A, A> right; 614 }
618 Function2<A, B> bot; 615 class E extends D {
619 616 int f(Object x) => /*info:DOWN_CAST_IMPLICIT*/x;
620 top = right; 617 }
621 top = bot; 618 class F extends E {
622 top = top; 619 int f(int x) => x;
623 top = left; 620 }
624 621 class G extends E implements D {}
625 left = /*warning:DownCastComposite*/top; 622
626 left = left; 623 class D_error extends C {
627 left = /*warning:DownCastComposite*/right; // Should we reject this? 624 /*error:INVALID_METHOD_OVERRIDE*/int f(String x) => 0;
628 left = bot; 625 }
629 626 class E_error extends D {
630 right = /*warning:DownCastComposite*/top; 627 /*error:INVALID_METHOD_OVERRIDE*/int f(double x) => 0;
631 right = /*warning:DownCastComposite*/left; // Should we reject this? 628 }
632 right = right; 629 class F_error extends E {
633 right = bot; 630 /*error:INVALID_METHOD_OVERRIDE*/int f(double x) => 0;
634 631 }
635 bot = /*warning:DownCastComposite*/top; 632 class G_error extends E implements D {
636 bot = /*warning:DownCastComposite*/left; 633 /*error:INVALID_METHOD_OVERRIDE*/int f(double x) => 0;
637 bot = /*warning:DownCastComposite*/right; 634 }
638 bot = bot; 635 ''');
639 } 636 }
640 } 637
641 ''' 638 void test_dynamicInvocation() {
642 }); 639 checkFile('''
643 640 typedef dynamic A(dynamic x);
644 testChecker('Function typing and subtyping: higher order function literals', { 641 class B {
645 '/main.dart': ''' 642 int call(int x) => x;
646 643 double col(double x) => x;
647 class A {} 644 }
648 class B extends A {} 645 void main() {
649 646 {
650 typedef T Function2<S, T>(S z); 647 B f = new B();
651 648 int x;
652 typedef A BToA(B x); // Top of the base lattice 649 double y;
653 typedef B AToB(A x); // Bot of the base lattice 650 x = f(3);
654 651 x = /*error:INVALID_ASSIGNMENT*/f.col(3.0);
655 BToA top(AToB f) => f; 652 y = /*error:INVALID_ASSIGNMENT*/f(3);
656 AToB left(AToB f) => f; 653 y = f.col(3.0);
657 BToA right(BToA f) => f; 654 f(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3.0);
658 AToB _bot(BToA f) => /*warning:DownCastComposite*/f; 655 f.col(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
659 AToB bot(BToA f) => f as AToB; 656 }
660 657 {
661 Function2<B, A> top(AToB f) => f; 658 Function f = new B();
662 Function2<A, B> left(AToB f) => f; 659 int x;
663 Function2<B, A> right(BToA f) => f; 660 double y;
664 Function2<A, B> _bot(BToA f) => /*warning:DownCastComposite*/f; 661 x = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
665 Function2<A, B> bot(BToA f) => f as Function2<A, B>; 662 x = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f.col(3.0);
666 663 y = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
667 664 y = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f.col(3.0);
668 BToA top(Function2<A, B> f) => f; 665 /*info:DYNAMIC_INVOKE*/f(3.0);
669 AToB left(Function2<A, B> f) => f; 666 // Through type propagation, we know f is actually a B, hence the
670 BToA right(Function2<B, A> f) => f; 667 // hint.
671 AToB _bot(Function2<B, A> f) => /*warning:DownCastComposite*/f; 668 /*info:DYNAMIC_INVOKE*/f.col(3);
672 AToB bot(Function2<B, A> f) => f as AToB; 669 }
673 670 {
674 void main() { 671 A f = new B();
675 { 672 int x;
676 Function2<AToB, BToA> f; // Top 673 double y;
677 f = top; 674 x = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
678 f = left; 675 y = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
679 f = right; 676 /*info:DYNAMIC_INVOKE*/f(3.0);
680 f = bot; 677 }
681 } 678 {
682 { 679 dynamic g = new B();
683 Function2<AToB, AToB> f; // Left 680 /*info:DYNAMIC_INVOKE*/g.call(32.0);
684 f = /*warning:DownCastComposite*/top; 681 /*info:DYNAMIC_INVOKE*/g.col(42.0);
685 f = left; 682 /*info:DYNAMIC_INVOKE*/g.foo(42.0);
686 f = /*warning:DownCastComposite*/right; // Should we reject this? 683 /*info:DYNAMIC_INVOKE*/g.x;
687 f = bot; 684 A f = new B();
688 } 685 /*info:DYNAMIC_INVOKE*/f.col(42.0);
689 { 686 /*info:DYNAMIC_INVOKE*/f.foo(42.0);
690 Function2<BToA, BToA> f; // Right 687 /*info:DYNAMIC_INVOKE*/f./*error:UNDEFINED_GETTER*/x;
691 f = /*warning:DownCastComposite*/top; 688 }
692 f = /*warning:DownCastComposite*/left; // Should we reject this? 689 }
693 f = right; 690 ''');
694 f = bot; 691 }
695 } 692
696 { 693 void test_factoryConstructorDowncast() {
697 Function2<BToA, AToB> f; // Bot 694 checkFile(r'''
698 f = bot; 695 class Animal {
699 f = /*warning:DownCastComposite*/left; 696 Animal();
700 f = /*warning:DownCastComposite*/top; 697 factory Animal.cat() => new Cat();
701 f = /*warning:DownCastComposite*/left; 698 }
702 } 699
703 } 700 class Cat extends Animal {}
704 ''' 701
705 }); 702 void main() {
706 703 Cat c = /*info:ASSIGNMENT_CAST*/new Animal.cat();
707 testChecker( 704 c = /*error:STATIC_TYPE_ERROR*/new Animal();
708 'Function typing and subtyping: higher order function variables', { 705 }''');
709 '/main.dart': ''' 706 }
710 707
711 class A {} 708 void test_fieldFieldOverride() {
712 class B extends A {} 709 checkFile('''
713 710 class A {}
714 typedef T Function2<S, T>(S z); 711 class B extends A {}
715 712 class C extends B {}
716 void main() { 713
717 { 714 class Base {
718 Function2<Function2<A, B>, Function2<B, A>> top; 715 B f1;
719 Function2<Function2<B, A>, Function2<B, A>> right; 716 B f2;
720 Function2<Function2<A, B>, Function2<A, B>> left; 717 B f3;
721 Function2<Function2<B, A>, Function2<A, B>> bot; 718 B f4;
722 719 }
723 top = right; 720
724 top = bot; 721 class Child extends Base {
725 top = top; 722 /*error:INVALID_FIELD_OVERRIDE,error:INVALID_METHOD_OVERRIDE*/A f1; // invalid for getter
726 top = left; 723 /*error:INVALID_FIELD_OVERRIDE,error:INVALID_METHOD_OVERRIDE*/C f2; // invalid for setter
727 724 /*error:INVALID_FIELD_OVERRIDE*/var f3;
728 left = /*warning:DownCastComposite*/top; 725 /*error:INVALID_FIELD_OVERRIDE,error:INVALID_METHOD_OVERRIDE*/dynamic f4;
729 left = left; 726 }
730 left = 727
731 /*warning:DownCastComposite should be severe:StaticTypeError*/right; 728 class Child2 implements Base {
732 left = bot; 729 /*error:INVALID_METHOD_OVERRIDE*/A f1; // invalid for getter
733 730 /*error:INVALID_METHOD_OVERRIDE*/C f2; // invalid for setter
734 right = /*warning:DownCastComposite*/top; 731 var f3;
735 right = 732 /*error:INVALID_METHOD_OVERRIDE*/dynamic f4;
736 /*warning:DownCastComposite should be severe:StaticTypeError*/left; 733 }
737 right = right; 734 ''');
738 right = bot; 735 }
739 736
740 bot = /*warning:DownCastComposite*/top; 737 void test_fieldGetterOverride() {
741 bot = /*warning:DownCastComposite*/left; 738 checkFile('''
742 bot = /*warning:DownCastComposite*/right; 739 class A {}
743 bot = bot; 740 class B extends A {}
744 } 741 class C extends B {}
742
743 abstract class Base {
744 B f1;
745 B f2;
746 B f3;
747 B f4;
748 }
749
750 class Child extends Base {
751 /*error:INVALID_FIELD_OVERRIDE,error:INVALID_METHOD_OVERRIDE*/A get f1 => null ;
752 /*error:INVALID_FIELD_OVERRIDE*/C get f2 => null;
753 /*error:INVALID_FIELD_OVERRIDE*/get f3 => null;
754 /*error:INVALID_FIELD_OVERRIDE,error:INVALID_METHOD_OVERRIDE*/dynamic get f4 = > null;
755 }
756
757 class /*error:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR*/Child2 implement s Base {
758 /*error:INVALID_METHOD_OVERRIDE*/A get f1 => null;
759 C get f2 => null;
760 get f3 => null;
761 /*error:INVALID_METHOD_OVERRIDE*/dynamic get f4 => null;
762 }
763 ''');
764 }
765
766 void test_fieldOverride_fuzzyArrows() {
767 checkFile('''
768 typedef void ToVoid<T>(T x);
769 class F {
770 final ToVoid<dynamic> f = null;
771 final ToVoid<int> g = null;
772 }
773
774 class G extends F {
775 /*error:INVALID_FIELD_OVERRIDE*/final ToVoid<int> f = null;
776 /*error:INVALID_FIELD_OVERRIDE, error:INVALID_METHOD_OVERRIDE*/final ToVoid<dy namic> g = null;
777 }
778
779 class H implements F {
780 final ToVoid<int> f = null;
781 /*error:INVALID_METHOD_OVERRIDE*/final ToVoid<dynamic> g = null;
782 }
783 ''');
784 }
785
786 void test_fieldOverride_virtual() {
787 _addMetaLibrary();
788 checkFile(r'''
789 import 'meta.dart';
790 class C {
791 @virtual int x;
792 }
793 class OverrideGetter extends C {
794 int get x => 42;
795 }
796 class OverrideSetter extends C {
797 set x(int v) {}
798 }
799 class OverrideBoth extends C {
800 int get x => 42;
801 set x(int v) {}
802 }
803 class OverrideWithField extends C {
804 int x;
805
806 // expose the hidden storage slot
807 int get superX => super.x;
808 set superX(int v) { super.x = v; }
809 }
810 class VirtualNotInherited extends OverrideWithField {
811 /*error:INVALID_FIELD_OVERRIDE*/int x;
812 }
813 ''');
814 }
815
816 void test_fieldSetterOverride() {
817 checkFile('''
818 class A {}
819 class B extends A {}
820 class C extends B {}
821
822 class Base {
823 B f1;
824 B f2;
825 B f3;
826 B f4;
827 B f5;
828 }
829
830 class Child extends Base {
831 /*error:INVALID_FIELD_OVERRIDE*/B get f1 => null;
832 /*error:INVALID_FIELD_OVERRIDE*/B get f2 => null;
833 /*error:INVALID_FIELD_OVERRIDE*/B get f3 => null;
834 /*error:INVALID_FIELD_OVERRIDE*/B get f4 => null;
835 /*error:INVALID_FIELD_OVERRIDE*/B get f5 => null;
836
837 /*error:INVALID_FIELD_OVERRIDE*/void set f1(A value) {}
838 /*error:INVALID_FIELD_OVERRIDE,error:INVALID_METHOD_OVERRIDE*/void set f2(C va lue) {}
839 /*error:INVALID_FIELD_OVERRIDE*/void set f3(value) {}
840 /*error:INVALID_FIELD_OVERRIDE*/void set f4(dynamic value) {}
841 /*error:INVALID_FIELD_OVERRIDE*/set f5(B value) {}
842 }
843
844 class Child2 implements Base {
845 B get f1 => null;
846 B get f2 => null;
847 B get f3 => null;
848 B get f4 => null;
849 B get f5 => null;
850
851 void set f1(A value) {}
852 /*error:INVALID_METHOD_OVERRIDE*/void set f2(C value) {}
853 void set f3(value) {}
854 void set f4(dynamic value) {}
855 set f5(B value) {}
856 }
857 ''');
858 }
859
860 void test_forInCastsIterateElementToVariable() {
861 checkFile('''
862 main() {
863 // Don't choke if sequence is not iterable.
864 for (var i in /*error:FOR_IN_OF_INVALID_TYPE*/1234) {}
865
866 // Dynamic cast.
867 for (String /*info:DYNAMIC_CAST*/s in <dynamic>[]) {}
868
869 // Identity cast.
870 for (String s in <String>[]) {}
871
872 // Untyped.
873 for (var s in <String>[]) {}
874
875 // Downcast.
876 for (int /*info:DOWN_CAST_IMPLICIT*/i in <num>[]) {}
877 }
878 ''');
879 }
880
881 void test_forInCastsSupertypeSequenceToIterate() {
882 checkFile('''
883 main() {
884 dynamic d;
885 for (var i in /*info:DYNAMIC_CAST*/d) {}
886
887 Object o;
888 for (var i in /*info:DOWN_CAST_IMPLICIT*/o) {}
889 }
890 ''');
891 }
892
893 void test_forLoopVariable() {
894 checkFile('''
895 foo() {
896 for (int i = 0; i < 10; i++) {
897 i = /*error:INVALID_ASSIGNMENT*/"hi";
898 }
899 }
900 bar() {
901 for (var i = 0; i < 10; i++) {
902 int j = i + 1;
903 }
904 }
905 ''');
906 }
907
908 void test_functionModifiers_async() {
909 checkFile('''
910 import 'dart:async';
911 import 'dart:math' show Random;
912
913 dynamic x;
914
915 foo1() async => x;
916 Future foo2() async => x;
917 Future<int> foo3() async => x;
918 Future<int> foo4() async => new Future<int>.value(/*info:DYNAMIC_CAST*/x);
919 Future<int> foo5() async =>
920 /*error:RETURN_OF_INVALID_TYPE*/new Future<String>.value(/*info:DYNAMIC_CAST */x);
921
922 bar1() async { return x; }
923 Future bar2() async { return x; }
924 Future<int> bar3() async { return x; }
925 Future<int> bar4() async { return new Future<int>.value(/*info:DYNAMIC_CAST*/x); }
926 Future<int> bar5() async {
927 return /*error:RETURN_OF_INVALID_TYPE*/new Future<String>.value(/*info:DYNAMIC _CAST*/x);
928 }
929
930 int y;
931 Future<int> z;
932
933 baz() async {
934 int a = /*info:DYNAMIC_CAST*/await x;
935 int b = await y;
936 int c = await z;
937 String d = /*error:INVALID_ASSIGNMENT*/await z;
938 }
939
940 Future<bool> get issue_ddc_264 async {
941 await 42;
942 if (new Random().nextBool()) {
943 return true;
944 } else {
945 return new Future<bool>.value(false);
946 }
947 }
948
949
950 Future<String> issue_sdk_26404() async {
951 return (1 > 0) ? new Future<String>.value('hello') : "world";
952 }
953 ''');
954 }
955
956 void test_functionModifiers_asyncStar() {
957 checkFile('''
958 import 'dart:async';
959
960 dynamic x;
961
962 bar1() async* { yield x; }
963 Stream bar2() async* { yield x; }
964 Stream<int> bar3() async* { yield /*info:DYNAMIC_CAST*/x; }
965 Stream<int> bar4() async* { yield /*error:YIELD_OF_INVALID_TYPE*/new Stream<int> (); }
966
967 baz1() async* { yield* /*info:DYNAMIC_CAST*/x; }
968 Stream baz2() async* { yield* /*info:DYNAMIC_CAST*/x; }
969 Stream<int> baz3() async* { yield* /*warning:DOWN_CAST_COMPOSITE*/x; }
970 Stream<int> baz4() async* { yield* new Stream<int>(); }
971 Stream<int> baz5() async* { yield* /*info:INFERRED_TYPE_ALLOCATION*/new Stream() ; }
972 ''');
973 }
974
975 void test_functionModifiers_syncStar() {
976 checkFile('''
977 dynamic x;
978
979 bar1() sync* { yield x; }
980 Iterable bar2() sync* { yield x; }
981 Iterable<int> bar3() sync* { yield /*info:DYNAMIC_CAST*/x; }
982 Iterable<int> bar4() sync* { yield /*error:YIELD_OF_INVALID_TYPE*/bar3(); }
983
984 baz1() sync* { yield* /*info:DYNAMIC_CAST*/x; }
985 Iterable baz2() sync* { yield* /*info:DYNAMIC_CAST*/x; }
986 Iterable<int> baz3() sync* { yield* /*warning:DOWN_CAST_COMPOSITE*/x; }
987 Iterable<int> baz4() sync* { yield* bar3(); }
988 Iterable<int> baz5() sync* { yield* /*info:INFERRED_TYPE_ALLOCATION*/new List(); }
989 ''');
990 }
991
992 void test_functionTypingAndSubtyping_classes() {
993 checkFile('''
994 class A {}
995 class B extends A {}
996
997 typedef A Top(B x); // Top of the lattice
998 typedef B Left(B x); // Left branch
999 typedef B Left2(B x); // Left branch
1000 typedef A Right(A x); // Right branch
1001 typedef B Bot(A x); // Bottom of the lattice
1002
1003 B left(B x) => x;
1004 B bot_(A x) => /*info:DOWN_CAST_IMPLICIT*/x;
1005 B bot(A x) => x as B;
1006 A top(B x) => x;
1007 A right(A x) => x;
1008
1009 void main() {
1010 { // Check typedef equality
1011 Left f = left;
1012 Left2 g = f;
1013 }
1014 {
1015 Top f;
1016 f = top;
1017 f = left;
1018 f = right;
1019 f = bot;
1020 }
1021 {
1022 Left f;
1023 f = /*error:STATIC_TYPE_ERROR*/top;
1024 f = left;
1025 f = /*error:INVALID_ASSIGNMENT*/right;
1026 f = bot;
1027 }
1028 {
1029 Right f;
1030 f = /*error:STATIC_TYPE_ERROR*/top;
1031 f = /*error:INVALID_ASSIGNMENT*/left;
1032 f = right;
1033 f = bot;
1034 }
1035 {
1036 Bot f;
1037 f = /*error:STATIC_TYPE_ERROR*/top;
1038 f = /*error:STATIC_TYPE_ERROR*/left;
1039 f = /*error:STATIC_TYPE_ERROR*/right;
1040 f = bot;
1041 }
1042 }
1043 ''');
1044 }
1045
1046 void test_functionTypingAndSubtyping_dynamic() {
1047 checkFile('''
1048 class A {}
1049
1050 typedef dynamic Top(dynamic x); // Top of the lattice
1051 typedef dynamic Left(A x); // Left branch
1052 typedef A Right(dynamic x); // Right branch
1053 typedef A Bottom(A x); // Bottom of the lattice
1054
1055 void main() {
1056 Top top;
1057 Left left;
1058 Right right;
1059 Bottom bot;
1060 {
1061 Top f;
1062 f = top;
1063 f = left;
1064 f = right;
1065 f = bot;
1066 }
1067 {
1068 Left f;
1069 f = /*warning:DOWN_CAST_COMPOSITE*/top;
1070 f = left;
1071 f = /*error:INVALID_ASSIGNMENT*/right;
1072 f = bot;
1073 }
1074 {
1075 Right f;
1076 f = /*warning:DOWN_CAST_COMPOSITE*/top;
1077 f = /*error:INVALID_ASSIGNMENT*/left;
1078 f = right;
1079 f = bot;
1080 }
1081 {
1082 Bottom f;
1083 f = /*warning:DOWN_CAST_COMPOSITE*/top;
1084 f = /*warning:DOWN_CAST_COMPOSITE*/left;
1085 f = /*warning:DOWN_CAST_COMPOSITE*/right;
1086 f = bot;
1087 }
1088 }
1089 ''');
1090 }
1091
1092 void test_functionTypingAndSubtyping_dynamic_knownFunctions() {
1093 // Our lattice should look like this:
1094 //
1095 //
1096 // Bot -> Top
1097 // / \
1098 // A -> Top Bot -> A
1099 // / \ /
1100 // Top -> Top A -> A
1101 // \ /
1102 // Top -> A
1103 //
1104 // Note that downcasts of known functions are promoted to
1105 // static type errors, since they cannot succeed.
1106 // This makes some of what look like downcasts turn into
1107 // type errors below.
1108 checkFile('''
1109 class A {}
1110
1111 typedef dynamic BotTop(dynamic x);
1112 typedef dynamic ATop(A x);
1113 typedef A BotA(dynamic x);
1114 typedef A AA(A x);
1115 typedef A TopA(Object x);
1116 typedef dynamic TopTop(Object x);
1117
1118 dynamic aTop(A x) => x;
1119 A aa(A x) => x;
1120 dynamic topTop(dynamic x) => x;
1121 A topA(dynamic x) => /*info:DYNAMIC_CAST*/x;
1122 void apply/*<T>*/(/*=T*/ f0, /*=T*/ f1, /*=T*/ f2,
1123 /*=T*/ f3, /*=T*/ f4, /*=T*/ f5) {}
1124 void main() {
1125 BotTop botTop;
1126 BotA botA;
1127 {
1128 BotTop f;
1129 f = topA;
1130 f = topTop;
1131 f = aa;
1132 f = aTop;
1133 f = botA;
1134 f = botTop;
1135 apply/*<BotTop>*/(
1136 topA,
1137 topTop,
1138 aa,
1139 aTop,
1140 botA,
1141 botTop
1142 );
1143 apply/*<BotTop>*/(
1144 (dynamic x) => new A(),
1145 (dynamic x) => (x as Object),
1146 (A x) => x,
1147 (A x) => null,
1148 botA,
1149 botTop
1150 );
1151 }
1152 {
1153 ATop f;
1154 f = topA;
1155 f = topTop;
1156 f = aa;
1157 f = aTop;
1158 f = /*error:INVALID_ASSIGNMENT*/botA;
1159 f = /*warning:DOWN_CAST_COMPOSITE*/botTop;
1160 apply/*<ATop>*/(
1161 topA,
1162 topTop,
1163 aa,
1164 aTop,
1165 /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/botA,
1166 /*warning:DOWN_CAST_COMPOSITE*/botTop
1167 );
1168 apply/*<ATop>*/(
1169 (dynamic x) => new A(),
1170 (dynamic x) => (x as Object),
1171 (A x) => x,
1172 (A x) => null,
1173 /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/botA,
1174 /*warning:DOWN_CAST_COMPOSITE*/botTop
1175 );
1176 }
1177 {
1178 BotA f;
1179 f = topA;
1180 f = /*error:INVALID_ASSIGNMENT*/topTop;
1181 f = aa;
1182 f = /*error:INVALID_ASSIGNMENT*/aTop;
1183 f = botA;
1184 f = /*warning:DOWN_CAST_COMPOSITE*/botTop;
1185 apply/*<BotA>*/(
1186 topA,
1187 /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/topTop,
1188 aa,
1189 /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/aTop,
1190 botA,
1191 /*warning:DOWN_CAST_COMPOSITE*/botTop
1192 );
1193 apply/*<BotA>*/(
1194 (dynamic x) => new A(),
1195 /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/(dynamic x) => (x as Object),
1196 (A x) => x,
1197 /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/(A x) => (/*info:UNNECESSARY_CAST* /x as Object),
1198 botA,
1199 /*warning:DOWN_CAST_COMPOSITE*/botTop
1200 );
1201 }
1202 {
1203 AA f;
1204 f = topA;
1205 f = /*error:INVALID_ASSIGNMENT*/topTop;
1206 f = aa;
1207 f = /*error:STATIC_TYPE_ERROR*/aTop; // known function
1208 f = /*warning:DOWN_CAST_COMPOSITE*/botA;
1209 f = /*warning:DOWN_CAST_COMPOSITE*/botTop;
1210 apply/*<AA>*/(
1211 topA,
1212 /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/topTop,
1213 aa,
1214 /*error:STATIC_TYPE_ERROR*/aTop, // known function
1215 /*warning:DOWN_CAST_COMPOSITE*/botA,
1216 /*warning:DOWN_CAST_COMPOSITE*/botTop
1217 );
1218 apply/*<AA>*/(
1219 (dynamic x) => new A(),
1220 /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/(dynamic x) => (x as Object),
1221 (A x) => x,
1222 /*error:STATIC_TYPE_ERROR*/(A x) => (/*info:UNNECESSARY_CAST*/x as Objec t), // known function
1223 /*warning:DOWN_CAST_COMPOSITE*/botA,
1224 /*warning:DOWN_CAST_COMPOSITE*/botTop
1225 );
1226 }
1227 {
1228 TopTop f;
1229 f = topA;
1230 f = topTop;
1231 f = /*error:INVALID_ASSIGNMENT*/aa;
1232 f = /*error:STATIC_TYPE_ERROR*/aTop; // known function
1233 f = /*error:INVALID_ASSIGNMENT*/botA;
1234 f = /*warning:DOWN_CAST_COMPOSITE*/botTop;
1235 apply/*<TopTop>*/(
1236 topA,
1237 topTop,
1238 /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/aa,
1239 /*error:STATIC_TYPE_ERROR*/aTop, // known function
1240 /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/botA,
1241 /*warning:DOWN_CAST_COMPOSITE*/botTop
1242 );
1243 apply/*<TopTop>*/(
1244 (dynamic x) => new A(),
1245 (dynamic x) => (x as Object),
1246 /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/(A x) => x,
1247 /*error:STATIC_TYPE_ERROR*/(A x) => (/*info:UNNECESSARY_CAST*/x as Objec t), // known function
1248 /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/botA,
1249 /*warning:DOWN_CAST_COMPOSITE*/botTop
1250 );
1251 }
1252 {
1253 TopA f;
1254 f = topA;
1255 f = /*error:STATIC_TYPE_ERROR*/topTop; // known function
1256 f = /*error:STATIC_TYPE_ERROR*/aa; // known function
1257 f = /*error:STATIC_TYPE_ERROR*/aTop; // known function
1258 f = /*warning:DOWN_CAST_COMPOSITE*/botA;
1259 f = /*warning:DOWN_CAST_COMPOSITE*/botTop;
1260 apply/*<TopA>*/(
1261 topA,
1262 /*error:STATIC_TYPE_ERROR*/topTop, // known function
1263 /*error:STATIC_TYPE_ERROR*/aa, // known function
1264 /*error:STATIC_TYPE_ERROR*/aTop, // known function
1265 /*warning:DOWN_CAST_COMPOSITE*/botA,
1266 /*warning:DOWN_CAST_COMPOSITE*/botTop
1267 );
1268 apply/*<TopA>*/(
1269 (dynamic x) => new A(),
1270 /*error:STATIC_TYPE_ERROR*/(dynamic x) => (x as Object), // known functi on
1271 /*error:STATIC_TYPE_ERROR*/(A x) => x, // known function
1272 /*error:STATIC_TYPE_ERROR*/(A x) => (/*info:UNNECESSARY_CAST*/x as Objec t), // known function
1273 /*warning:DOWN_CAST_COMPOSITE*/botA,
1274 /*warning:DOWN_CAST_COMPOSITE*/botTop
1275 );
1276 }
1277 }
1278 ''');
1279 }
1280
1281 void test_functionTypingAndSubtyping_dynamicFunctions_clasuresAreNotFuzzy() {
1282 // Regression test for
1283 // https://github.com/dart-lang/sdk/issues/26118
1284 // https://github.com/dart-lang/sdk/issues/26156
1285 checkFile('''
1286 void takesF(void f(int x)) {}
1287
1288 typedef void TakesInt(int x);
1289
1290 void update(_) {}
1291 void updateOpt([_]) {}
1292 void updateOptNum([num x]) {}
1293
1294 class A {
1295 TakesInt f;
1296 A(TakesInt g) {
1297 f = update;
1298 f = updateOpt;
1299 f = updateOptNum;
1300 }
1301 TakesInt g(bool a, bool b) {
1302 if (a) {
1303 return update;
1304 } else if (b) {
1305 return updateOpt;
1306 } else {
1307 return updateOptNum;
745 } 1308 }
746 ''' 1309 }
747 }); 1310 }
748 1311
749 testChecker('Function typing and subtyping: named and optional parameters', { 1312 void test0() {
750 '/main.dart': ''' 1313 takesF(update);
751 1314 takesF(updateOpt);
752 class A {} 1315 takesF(updateOptNum);
753 1316 TakesInt f;
754 typedef A FR(A x); 1317 f = update;
755 typedef A FO([A x]); 1318 f = updateOpt;
756 typedef A FN({A x}); 1319 f = updateOptNum;
757 typedef A FRR(A x, A y); 1320 new A(update);
758 typedef A FRO(A x, [A y]); 1321 new A(updateOpt);
759 typedef A FRN(A x, {A n}); 1322 new A(updateOptNum);
760 typedef A FOO([A x, A y]); 1323 }
761 typedef A FNN({A x, A y}); 1324
762 typedef A FNNN({A z, A y, A x}); 1325 void test1() {
763 1326 void takesF(f(int x)) => null;
764 void main() { 1327 takesF((dynamic y) => 3);
765 FR r; 1328 }
766 FO o; 1329
767 FN n; 1330 void test2() {
768 FRR rr; 1331 int x;
769 FRO ro; 1332 int f/*<T>*/(/*=T*/ t, callback(/*=T*/ x)) { return 3; }
770 FRN rn; 1333 f(x, (y) => 3);
771 FOO oo; 1334 }
772 FNN nn; 1335 ''');
773 FNNN nnn; 1336 }
774 1337
775 r = r; 1338 void test_functionTypingAndSubtyping_functionLiteralVariance() {
776 r = o; 1339 checkFile('''
777 r = /*severe:StaticTypeError*/n; 1340 class A {}
778 r = /*severe:StaticTypeError*/rr; 1341 class B extends A {}
779 r = ro; 1342
780 r = rn; 1343 typedef T Function2<S, T>(S z);
781 r = oo; 1344
782 r = /*severe:StaticTypeError*/nn; 1345 A top(B x) => x;
783 r = /*severe:StaticTypeError*/nnn; 1346 B left(B x) => x;
784 1347 A right(A x) => x;
785 o = /*warning:DownCastComposite*/r; 1348 B bot(A x) => x as B;
786 o = o; 1349
787 o = /*severe:StaticTypeError*/n; 1350 void main() {
788 o = /*severe:StaticTypeError*/rr; 1351 {
789 o = /*severe:StaticTypeError*/ro; 1352 Function2<B, A> f;
790 o = /*severe:StaticTypeError*/rn; 1353 f = top;
791 o = oo; 1354 f = left;
792 o = /*severe:StaticTypeError*/nn 1355 f = right;
793 o = /*severe:StaticTypeError*/nnn; 1356 f = bot;
794 1357 }
795 n = /*severe:StaticTypeError*/r; 1358 {
796 n = /*severe:StaticTypeError*/o; 1359 Function2<B, B> f; // left
797 n = n; 1360 f = /*error:STATIC_TYPE_ERROR*/top;
798 n = /*severe:StaticTypeError*/rr; 1361 f = left;
799 n = /*severe:StaticTypeError*/ro; 1362 f = /*error:INVALID_ASSIGNMENT*/right;
800 n = /*severe:StaticTypeError*/rn; 1363 f = bot;
801 n = /*severe:StaticTypeError*/oo; 1364 }
802 n = nn; 1365 {
803 n = nnn; 1366 Function2<A, A> f; // right
804 1367 f = /*error:STATIC_TYPE_ERROR*/top;
805 rr = /*severe:StaticTypeError*/r; 1368 f = /*error:INVALID_ASSIGNMENT*/left;
806 rr = /*severe:StaticTypeError*/o; 1369 f = right;
807 rr = /*severe:StaticTypeError*/n; 1370 f = bot;
808 rr = rr; 1371 }
809 rr = ro; 1372 {
810 rr = /*severe:StaticTypeError*/rn; 1373 Function2<A, B> f;
811 rr = oo; 1374 f = /*error:STATIC_TYPE_ERROR*/top;
812 rr = /*severe:StaticTypeError*/nn; 1375 f = /*error:STATIC_TYPE_ERROR*/left;
813 rr = /*severe:StaticTypeError*/nnn; 1376 f = /*error:STATIC_TYPE_ERROR*/right;
814 1377 f = bot;
815 ro = /*warning:DownCastComposite*/r; 1378 }
816 ro = /*severe:StaticTypeError*/o; 1379 }
817 ro = /*severe:StaticTypeError*/n; 1380 ''');
818 ro = /*warning:DownCastComposite*/rr; 1381 }
819 ro = ro; 1382
820 ro = /*severe:StaticTypeError*/rn; 1383 void test_functionTypingAndSubtyping_functionVariableVariance() {
821 ro = oo; 1384 checkFile('''
822 ro = /*severe:StaticTypeError*/nn; 1385 class A {}
823 ro = /*severe:StaticTypeError*/nnn; 1386 class B extends A {}
824 1387
825 rn = /*warning:DownCastComposite*/r; 1388 typedef T Function2<S, T>(S z);
826 rn = /*severe:StaticTypeError*/o; 1389
827 rn = /*severe:StaticTypeError*/n; 1390 void main() {
828 rn = /*severe:StaticTypeError*/rr; 1391 {
829 rn = /*severe:StaticTypeError*/ro; 1392 Function2<B, A> top;
830 rn = rn; 1393 Function2<B, B> left;
831 rn = /*severe:StaticTypeError*/oo; 1394 Function2<A, A> right;
832 rn = /*severe:StaticTypeError*/nn; 1395 Function2<A, B> bot;
833 rn = /*severe:StaticTypeError*/nnn; 1396
834 1397 top = right;
835 oo = /*warning:DownCastComposite*/r; 1398 top = bot;
836 oo = /*warning:DownCastComposite*/o; 1399 top = top;
837 oo = /*severe:StaticTypeError*/n; 1400 top = left;
838 oo = /*warning:DownCastComposite*/rr; 1401
839 oo = /*warning:DownCastComposite*/ro; 1402 left = /*warning:DOWN_CAST_COMPOSITE*/top;
840 oo = /*severe:StaticTypeError*/rn; 1403 left = left;
841 oo = oo; 1404 left = /*error:INVALID_ASSIGNMENT*/right;
842 oo = /*severe:StaticTypeError*/nn; 1405 left = bot;
843 oo = /*severe:StaticTypeError*/nnn; 1406
844 1407 right = /*warning:DOWN_CAST_COMPOSITE*/top;
845 nn = /*severe:StaticTypeError*/r; 1408 right = /*error:INVALID_ASSIGNMENT*/left;
846 nn = /*severe:StaticTypeError*/o; 1409 right = right;
847 nn = /*warning:DownCastComposite*/n; 1410 right = bot;
848 nn = /*severe:StaticTypeError*/rr; 1411
849 nn = /*severe:StaticTypeError*/ro; 1412 bot = /*warning:DOWN_CAST_COMPOSITE*/top;
850 nn = /*severe:StaticTypeError*/rn; 1413 bot = /*warning:DOWN_CAST_COMPOSITE*/left;
851 nn = /*severe:StaticTypeError*/oo; 1414 bot = /*warning:DOWN_CAST_COMPOSITE*/right;
852 nn = nn; 1415 bot = bot;
853 nn = nnn; 1416 }
854 1417 }
855 nnn = /*severe:StaticTypeError*/r; 1418 ''');
856 nnn = /*severe:StaticTypeError*/o; 1419 }
857 nnn = /*warning:DownCastComposite*/n; 1420
858 nnn = /*severe:StaticTypeError*/rr; 1421 void test_functionTypingAndSubtyping_higherOrderFunctionLiteral1() {
859 nnn = /*severe:StaticTypeError*/ro; 1422 checkFile('''
860 nnn = /*severe:StaticTypeError*/rn; 1423 class A {}
861 nnn = /*severe:StaticTypeError*/oo; 1424 class B extends A {}
862 nnn = /*warning:DownCastComposite*/nn; 1425
863 nnn = nnn; 1426 typedef T Function2<S, T>(S z);
864 } 1427
865 ''' 1428 typedef A BToA(B x); // Top of the base lattice
866 }); 1429 typedef B AToB(A x); // Bot of the base lattice
867 1430
868 testChecker('Function subtyping: objects with call methods', { 1431 BToA top(AToB f) => f;
869 '/main.dart': ''' 1432 AToB left(AToB f) => f;
870 1433 BToA right(BToA f) => f;
871 typedef int I2I(int x); 1434 AToB bot_(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f;
872 typedef num N2N(num x); 1435 AToB bot(BToA f) => f as AToB;
873 class A { 1436
874 int call(int x) => x; 1437 void main() {
875 } 1438 {
876 class B { 1439 Function2<AToB, BToA> f; // Top
877 num call(num x) => x; 1440 f = top;
878 } 1441 f = left;
879 int i2i(int x) => x; 1442 f = right;
880 num n2n(num x) => x; 1443 f = bot;
881 void main() { 1444 }
882 { 1445 {
883 I2I f; 1446 Function2<AToB, AToB> f; // Left
884 f = new A(); 1447 f = /*error:STATIC_TYPE_ERROR*/top;
885 f = /*severe:StaticTypeError*/new B(); 1448 f = left;
886 f = i2i; 1449 f = /*error:INVALID_ASSIGNMENT*/right;
887 f = /*warning:DownCastComposite*/n2n; 1450 f = bot;
888 f = /*warning:DownCastComposite*/i2i as Object; 1451 }
889 f = /*warning:DownCastComposite*/n2n as Function; 1452 {
890 } 1453 Function2<BToA, BToA> f; // Right
891 { 1454 f = /*error:STATIC_TYPE_ERROR*/top;
892 N2N f; 1455 f = /*error:INVALID_ASSIGNMENT*/left;
893 f = /*severe:StaticTypeError*/new A(); 1456 f = right;
894 f = new B(); 1457 f = bot;
895 f = /*warning:DownCastComposite*/i2i; 1458 }
896 f = n2n; 1459 {
897 f = /*warning:DownCastComposite*/i2i as Object; 1460 Function2<BToA, AToB> f; // Bot
898 f = /*warning:DownCastComposite*/n2n as Function; 1461 f = bot;
899 } 1462 f = /*error:STATIC_TYPE_ERROR*/left;
900 { 1463 f = /*error:STATIC_TYPE_ERROR*/top;
901 A f; 1464 f = /*error:STATIC_TYPE_ERROR*/right;
902 f = new A(); 1465 }
903 f = /*severe:StaticTypeError*/new B(); 1466 }
904 f = /*severe:StaticTypeError*/i2i; 1467 ''');
905 f = /*severe:StaticTypeError*/n2n; 1468 }
906 f = /*info:DownCastImplicit*/i2i as Object; 1469
907 f = /*info:DownCastImplicit*/n2n as Function; 1470 void test_functionTypingAndSubtyping_higherOrderFunctionLiteral2() {
908 } 1471 checkFile('''
909 { 1472 class A {}
910 B f; 1473 class B extends A {}
911 f = /*severe:StaticTypeError*/new A(); 1474
912 f = new B(); 1475 typedef T Function2<S, T>(S z);
913 f = /*severe:StaticTypeError*/i2i; 1476
914 f = /*severe:StaticTypeError*/n2n; 1477 typedef A BToA(B x); // Top of the base lattice
915 f = /*info:DownCastImplicit*/i2i as Object; 1478 typedef B AToB(A x); // Bot of the base lattice
916 f = /*info:DownCastImplicit*/n2n as Function; 1479
917 } 1480 Function2<B, A> top(AToB f) => f;
918 { 1481 Function2<A, B> left(AToB f) => f;
919 Function f; 1482 Function2<B, A> right(BToA f) => f;
920 f = new A(); 1483 Function2<A, B> bot_(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f;
921 f = new B(); 1484 Function2<A, B> bot(BToA f) => f as Function2<A, B>;
922 f = i2i; 1485
923 f = n2n; 1486 void main() {
924 f = /*info:DownCastImplicit*/i2i as Object; 1487 {
925 f = (n2n as Function); 1488 Function2<AToB, BToA> f; // Top
926 } 1489 f = top;
927 } 1490 f = left;
928 ''' 1491 f = right;
929 }); 1492 f = bot;
930 1493 }
931 testChecker('Function typing and subtyping: void', { 1494 {
932 '/main.dart': ''' 1495 Function2<AToB, AToB> f; // Left
933 1496 f = /*error:STATIC_TYPE_ERROR*/top;
934 class A { 1497 f = left;
935 void bar() => null; 1498 f = /*error:INVALID_ASSIGNMENT*/right;
936 void foo() => bar; // allowed 1499 f = bot;
937 } 1500 }
938 ''' 1501 {
939 }); 1502 Function2<BToA, BToA> f; // Right
940 1503 f = /*error:STATIC_TYPE_ERROR*/top;
941 testChecker('Relaxed casts', { 1504 f = /*error:INVALID_ASSIGNMENT*/left;
942 '/main.dart': ''' 1505 f = right;
943 1506 f = bot;
944 class A {} 1507 }
945 1508 {
946 class L<T> {} 1509 Function2<BToA, AToB> f; // Bot
947 class M<T> extends L<T> {} 1510 f = bot;
948 // L<dynamic|Object> 1511 f = /*error:STATIC_TYPE_ERROR*/left;
949 // / \ 1512 f = /*error:STATIC_TYPE_ERROR*/top;
950 // M<dynamic|Object> L<A> 1513 f = /*error:STATIC_TYPE_ERROR*/right;
951 // \ / 1514 }
952 // M<A> 1515 }
953 // In normal Dart, there are additional edges 1516 ''');
954 // from M<A> to M<dynamic> 1517 }
955 // from L<A> to M<dynamic> 1518
956 // from L<A> to L<dynamic> 1519 void test_functionTypingAndSubtyping_higherOrderFunctionLiteral3() {
957 void main() { 1520 checkFile('''
958 L lOfDs; 1521 class A {}
959 L<Object> lOfOs; 1522 class B extends A {}
960 L<A> lOfAs; 1523
961 1524 typedef T Function2<S, T>(S z);
962 M mOfDs; 1525
963 M<Object> mOfOs; 1526 typedef A BToA(B x); // Top of the base lattice
964 M<A> mOfAs; 1527 typedef B AToB(A x); // Bot of the base lattice
965 1528
966 { 1529 BToA top(Function2<A, B> f) => f;
967 lOfDs = mOfDs; 1530 AToB left(Function2<A, B> f) => f;
968 lOfDs = mOfOs; 1531 BToA right(Function2<B, A> f) => f;
969 lOfDs = mOfAs; 1532 AToB bot_(Function2<B, A> f) => /*warning:DOWN_CAST_COMPOSITE*/f;
970 lOfDs = lOfDs; 1533 AToB bot(Function2<B, A> f) => f as AToB;
971 lOfDs = lOfOs; 1534
972 lOfDs = lOfAs; 1535 void main() {
973 } 1536 {
974 { 1537 Function2<AToB, BToA> f; // Top
975 lOfOs = mOfDs; 1538 f = top;
976 lOfOs = mOfOs; 1539 f = left;
977 lOfOs = mOfAs; 1540 f = right;
978 lOfOs = lOfDs; 1541 f = bot;
979 lOfOs = lOfOs; 1542 }
980 lOfOs = lOfAs; 1543 {
981 } 1544 Function2<AToB, AToB> f; // Left
982 { 1545 f = /*error:STATIC_TYPE_ERROR*/top;
983 lOfAs = /*warning:DownCastComposite*/mOfDs; 1546 f = left;
984 lOfAs = /*severe:StaticTypeError*/mOfOs; 1547 f = /*error:INVALID_ASSIGNMENT*/right;
985 lOfAs = mOfAs; 1548 f = bot;
986 lOfAs = /*warning:DownCastComposite*/lOfDs; 1549 }
987 lOfAs = /*warning:DownCastComposite*/lOfOs; 1550 {
988 lOfAs = lOfAs; 1551 Function2<BToA, BToA> f; // Right
989 } 1552 f = /*error:STATIC_TYPE_ERROR*/top;
990 { 1553 f = /*error:INVALID_ASSIGNMENT*/left;
991 mOfDs = mOfDs; 1554 f = right;
992 mOfDs = mOfOs; 1555 f = bot;
993 mOfDs = mOfAs; 1556 }
994 mOfDs = /*info:DownCastImplicit*/lOfDs; 1557 {
995 mOfDs = /*info:DownCastImplicit*/lOfOs; 1558 Function2<BToA, AToB> f; // Bot
996 mOfDs = /*info:DownCastImplicit*/lOfAs; 1559 f = bot;
997 } 1560 f = /*error:STATIC_TYPE_ERROR*/left;
998 { 1561 f = /*error:STATIC_TYPE_ERROR*/top;
999 mOfOs = mOfDs; 1562 f = /*error:STATIC_TYPE_ERROR*/right;
1000 mOfOs = mOfOs; 1563 }
1001 mOfOs = mOfAs; 1564 }
1002 mOfOs = /*info:DownCastImplicit*/lOfDs; 1565 ''');
1003 mOfOs = /*info:DownCastImplicit*/lOfOs; 1566 }
1004 mOfOs = /*severe:StaticTypeError*/lOfAs; 1567
1005 } 1568 void test_functionTypingAndSubtyping_higherOrderFunctionVariables() {
1006 { 1569 checkFile('''
1007 mOfAs = /*warning:DownCastComposite*/mOfDs; 1570 class A {}
1008 mOfAs = /*warning:DownCastComposite*/mOfOs; 1571 class B extends A {}
1009 mOfAs = mOfAs; 1572
1010 mOfAs = /*warning:DownCastComposite*/lOfDs; 1573 typedef T Function2<S, T>(S z);
1011 mOfAs = /*warning:DownCastComposite*/lOfOs; 1574
1012 mOfAs = /*warning:DownCastComposite*/lOfAs; 1575 void main() {
1013 } 1576 {
1014 1577 Function2<Function2<A, B>, Function2<B, A>> top;
1015 } 1578 Function2<Function2<B, A>, Function2<B, A>> right;
1016 ''' 1579 Function2<Function2<A, B>, Function2<A, B>> left;
1017 }); 1580 Function2<Function2<B, A>, Function2<A, B>> bot;
1018 1581
1019 testChecker('Type checking literals', { 1582 top = right;
1020 '/main.dart': ''' 1583 top = bot;
1021 test() { 1584 top = top;
1022 num n = 3; 1585 top = left;
1023 int i = 3; 1586
1024 String s = "hello"; 1587 left = /*warning:DOWN_CAST_COMPOSITE*/top;
1025 { 1588 left = left;
1026 List<int> l = <int>[i]; 1589 left =
1027 l = <int>[/*severe:StaticTypeError*/s]; 1590 /*error:INVALID_ASSIGNMENT*/right;
1028 l = <int>[/*info:DownCastImplicit*/n]; 1591 left = bot;
1029 l = <int>[i, /*info:DownCastImplicit*/n, /*severe:StaticTypeError */s]; 1592
1030 } 1593 right = /*warning:DOWN_CAST_COMPOSITE*/top;
1031 { 1594 right =
1032 List l = [i]; 1595 /*error:INVALID_ASSIGNMENT*/left;
1033 l = [s]; 1596 right = right;
1034 l = [n]; 1597 right = bot;
1035 l = [i, n, s]; 1598
1036 } 1599 bot = /*warning:DOWN_CAST_COMPOSITE*/top;
1037 { 1600 bot = /*warning:DOWN_CAST_COMPOSITE*/left;
1038 Map<String, int> m = <String, int>{s: i}; 1601 bot = /*warning:DOWN_CAST_COMPOSITE*/right;
1039 m = <String, int>{s: /*severe:StaticTypeError*/s}; 1602 bot = bot;
1040 m = <String, int>{s: /*info:DownCastImplicit*/n}; 1603 }
1041 m = <String, int>{s: i, 1604 }
1042 s: /*info:DownCastImplicit*/n, 1605 ''');
1043 s: /*severe:StaticTypeError*/s}; 1606 }
1044 } 1607
1045 // TODO(leafp): We can't currently test for key errors since the 1608 void test_functionTypingAndSubtyping_instanceMethodVariance() {
1046 // error marker binds to the entire entry. 1609 checkFile('''
1047 { 1610 class A {}
1048 Map m = {s: i}; 1611 class B extends A {}
1049 m = {s: s}; 1612
1050 m = {s: n}; 1613 class C {
1051 m = {s: i, 1614 A top(B x) => x;
1052 s: n, 1615 B left(B x) => x;
1053 s: s}; 1616 A right(A x) => x;
1054 m = {i: s, 1617 B bot(A x) => x as B;
1055 n: s, 1618 }
1056 s: s}; 1619
1057 } 1620 typedef T Function2<S, T>(S z);
1058 } 1621
1059 ''' 1622 void main() {
1060 }); 1623 C c = new C();
1061 1624 {
1062 testChecker('casts in constant contexts', { 1625 Function2<B, A> f;
1063 '/main.dart': ''' 1626 f = c.top;
1064 class A { 1627 f = c.left;
1065 static const num n = 3.0; 1628 f = c.right;
1066 static const int i = /*info:AssignmentCast*/n; 1629 f = c.bot;
1067 final int fi; 1630 }
1068 const A(num a) : this.fi = /*info:DownCastImplicit*/a; 1631 {
1069 } 1632 Function2<B, B> f;
1070 class B extends A { 1633 f = /*warning:DOWN_CAST_COMPOSITE*/c.top;
1071 const B(Object a) : super(/*info:DownCastImplicit*/a); 1634 f = c.left;
1072 } 1635 f = /*error:INVALID_ASSIGNMENT*/c.right;
1073 void foo(Object o) { 1636 f = c.bot;
1074 var a = const A(/*info:DownCastImplicit*/o); 1637 }
1075 } 1638 {
1076 ''' 1639 Function2<A, A> f;
1077 }); 1640 f = /*warning:DOWN_CAST_COMPOSITE*/c.top;
1078 1641 f = /*error:INVALID_ASSIGNMENT*/c.left;
1079 testChecker('casts in conditionals', { 1642 f = c.right;
1080 '/main.dart': ''' 1643 f = c.bot;
1081 main() { 1644 }
1082 bool b = true; 1645 {
1083 num x = b ? 1 : 2.3; 1646 Function2<A, B> f;
1084 int y = /*info:AssignmentCast*/b ? 1 : 2.3; 1647 f = /*warning:DOWN_CAST_COMPOSITE*/c.top;
1085 String z = !b ? "hello" : null; 1648 f = /*warning:DOWN_CAST_COMPOSITE*/c.left;
1086 z = b ? null : "hello"; 1649 f = /*warning:DOWN_CAST_COMPOSITE*/c.right;
1087 } 1650 f = c.bot;
1088 ''' 1651 }
1089 }); 1652 }
1090 1653 ''');
1091 testChecker('redirecting constructor', { 1654 }
1092 '/main.dart': ''' 1655
1093 class A { 1656 void test_functionTypingAndSubtyping_intAndObject() {
1094 A(A x) {} 1657 checkFile('''
1095 A.two() : this(/*severe:StaticTypeError*/3); 1658 typedef Object Top(int x); // Top of the lattice
1096 } 1659 typedef int Left(int x); // Left branch
1097 ''' 1660 typedef int Left2(int x); // Left branch
1098 }); 1661 typedef Object Right(Object x); // Right branch
1099 1662 typedef int Bot(Object x); // Bottom of the lattice
1100 testChecker('super constructor', { 1663
1101 '/main.dart': ''' 1664 Object globalTop(int x) => x;
1102 class A { A(A x) {} } 1665 int globalLeft(int x) => x;
1103 class B extends A { 1666 Object globalRight(Object x) => x;
1104 B() : super(/*severe:StaticTypeError*/3); 1667 int bot_(Object x) => /*info:DOWN_CAST_IMPLICIT*/x;
1105 } 1668 int globalBot(Object x) => x as int;
1106 ''' 1669
1107 }); 1670 void main() {
1108 1671 // Note: use locals so we only know the type, not that it's a specific
1109 testChecker('field/field override', { 1672 // function declaration. (we can issue better errors in that case.)
1110 '/main.dart': ''' 1673 var top = globalTop;
1111 class A {} 1674 var left = globalLeft;
1112 class B extends A {} 1675 var right = globalRight;
1113 class C extends B {} 1676 var bot = globalBot;
1114 1677
1115 class Base { 1678 { // Check typedef equality
1116 B f1; 1679 Left f = left;
1117 B f2; 1680 Left2 g = f;
1118 B f3; 1681 }
1119 B f4; 1682 {
1120 } 1683 Top f;
1121 1684 f = top;
1122 class Child extends Base { 1685 f = left;
1123 /*severe:InvalidMethodOverride*/A f1; // invalid for getter 1686 f = right;
1124 /*severe:InvalidMethodOverride*/C f2; // invalid for setter 1687 f = bot;
1125 var f3; 1688 }
1126 /*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/dynamic f4; 1689 {
1127 } 1690 Left f;
1128 ''' 1691 f = /*warning:DOWN_CAST_COMPOSITE*/top;
1129 }); 1692 f = left;
1130 1693 f = /*error:INVALID_ASSIGNMENT*/right;
1131 testChecker('getter/getter override', { 1694 f = bot;
1132 '/main.dart': ''' 1695 }
1133 class A {} 1696 {
1134 class B extends A {} 1697 Right f;
1135 class C extends B {} 1698 f = /*warning:DOWN_CAST_COMPOSITE*/top;
1136 1699 f = /*error:INVALID_ASSIGNMENT*/left;
1137 abstract class Base { 1700 f = right;
1138 B get f1; 1701 f = bot;
1139 B get f2; 1702 }
1140 B get f3; 1703 {
1141 B get f4; 1704 Bot f;
1142 } 1705 f = /*warning:DOWN_CAST_COMPOSITE*/top;
1143 1706 f = /*warning:DOWN_CAST_COMPOSITE*/left;
1144 class Child extends Base { 1707 f = /*warning:DOWN_CAST_COMPOSITE*/right;
1145 /*severe:InvalidMethodOverride*/A get f1 => null; 1708 f = bot;
1146 C get f2 => null; 1709 }
1147 get f3 => null; 1710 }
1148 /*severe:InvalidMethodOverride*/dynamic get f4 => null; 1711 ''');
1149 } 1712 }
1150 ''' 1713
1151 }); 1714 void test_functionTypingAndSubtyping_namedAndOptionalParameters() {
1152 1715 checkFile('''
1153 testChecker('field/getter override', { 1716 class A {}
1154 '/main.dart': ''' 1717
1155 class A {} 1718 typedef A FR(A x);
1156 class B extends A {} 1719 typedef A FO([A x]);
1157 class C extends B {} 1720 typedef A FN({A x});
1158 1721 typedef A FRR(A x, A y);
1159 abstract class Base { 1722 typedef A FRO(A x, [A y]);
1160 B f1; 1723 typedef A FRN(A x, {A n});
1161 B f2; 1724 typedef A FOO([A x, A y]);
1162 B f3; 1725 typedef A FNN({A x, A y});
1163 B f4; 1726 typedef A FNNN({A z, A y, A x});
1164 } 1727
1165 1728 void main() {
1166 class Child extends Base { 1729 FR r;
1167 /*severe:InvalidMethodOverride*/A get f1 => null; 1730 FO o;
1168 C get f2 => null; 1731 FN n;
1169 get f3 => null; 1732 FRR rr;
1170 /*severe:InvalidMethodOverride*/dynamic get f4 => null; 1733 FRO ro;
1171 } 1734 FRN rn;
1172 ''' 1735 FOO oo;
1173 }); 1736 FNN nn;
1174 1737 FNNN nnn;
1175 testChecker('setter/setter override', { 1738
1176 '/main.dart': ''' 1739 r = r;
1177 class A {} 1740 r = o;
1178 class B extends A {} 1741 r = /*error:INVALID_ASSIGNMENT*/n;
1179 class C extends B {} 1742 r = /*error:INVALID_ASSIGNMENT*/rr;
1180 1743 r = ro;
1181 abstract class Base { 1744 r = rn;
1182 void set f1(B value); 1745 r = oo;
1183 void set f2(B value); 1746 r = /*error:INVALID_ASSIGNMENT*/nn;
1184 void set f3(B value); 1747 r = /*error:INVALID_ASSIGNMENT*/nnn;
1185 void set f4(B value); 1748
1186 void set f5(B value); 1749 o = /*warning:DOWN_CAST_COMPOSITE*/r;
1187 } 1750 o = o;
1188 1751 o = /*error:INVALID_ASSIGNMENT*/n;
1189 class Child extends Base { 1752 o = /*error:INVALID_ASSIGNMENT*/rr;
1190 void set f1(A value) {} 1753 o = /*error:INVALID_ASSIGNMENT*/ro;
1191 /*severe:InvalidMethodOverride*/void set f2(C value) {} 1754 o = /*error:INVALID_ASSIGNMENT*/rn;
1192 void set f3(value) {} 1755 o = oo;
1193 /*severe:InvalidMethodOverride*/void set f4(dynamic value) {} 1756 o = /*error:INVALID_ASSIGNMENT*/nn;
1194 set f5(B value) {} 1757 o = /*error:INVALID_ASSIGNMENT*/nnn;
1195 } 1758
1196 ''' 1759 n = /*error:INVALID_ASSIGNMENT*/r;
1197 }); 1760 n = /*error:INVALID_ASSIGNMENT*/o;
1198 1761 n = n;
1199 testChecker('field/setter override', { 1762 n = /*error:INVALID_ASSIGNMENT*/rr;
1200 '/main.dart': ''' 1763 n = /*error:INVALID_ASSIGNMENT*/ro;
1201 class A {} 1764 n = /*error:INVALID_ASSIGNMENT*/rn;
1202 class B extends A {} 1765 n = /*error:INVALID_ASSIGNMENT*/oo;
1203 class C extends B {} 1766 n = nn;
1204 1767 n = nnn;
1205 class Base { 1768
1206 B f1; 1769 rr = /*error:INVALID_ASSIGNMENT*/r;
1207 B f2; 1770 rr = /*error:INVALID_ASSIGNMENT*/o;
1208 B f3; 1771 rr = /*error:INVALID_ASSIGNMENT*/n;
1209 B f4; 1772 rr = rr;
1210 B f5; 1773 rr = ro;
1211 } 1774 rr = /*error:INVALID_ASSIGNMENT*/rn;
1212 1775 rr = oo;
1213 class Child extends Base { 1776 rr = /*error:INVALID_ASSIGNMENT*/nn;
1214 B get f1 => null; 1777 rr = /*error:INVALID_ASSIGNMENT*/nnn;
1215 B get f2 => null; 1778
1216 B get f3 => null; 1779 ro = /*warning:DOWN_CAST_COMPOSITE*/r;
1217 B get f4 => null; 1780 ro = /*error:INVALID_ASSIGNMENT*/o;
1218 B get f5 => null; 1781 ro = /*error:INVALID_ASSIGNMENT*/n;
1219 1782 ro = /*warning:DOWN_CAST_COMPOSITE*/rr;
1220 void set f1(A value) {} 1783 ro = ro;
1221 /*severe:InvalidMethodOverride*/void set f2(C value) {} 1784 ro = /*error:INVALID_ASSIGNMENT*/rn;
1222 void set f3(value) {} 1785 ro = oo;
1223 /*severe:InvalidMethodOverride*/void set f4(dynamic value) {} 1786 ro = /*error:INVALID_ASSIGNMENT*/nn;
1224 set f5(B value) {} 1787 ro = /*error:INVALID_ASSIGNMENT*/nnn;
1225 } 1788
1226 ''' 1789 rn = /*warning:DOWN_CAST_COMPOSITE*/r;
1227 }); 1790 rn = /*error:INVALID_ASSIGNMENT*/o;
1228 1791 rn = /*error:INVALID_ASSIGNMENT*/n;
1229 testChecker('method override', { 1792 rn = /*error:INVALID_ASSIGNMENT*/rr;
1230 '/main.dart': ''' 1793 rn = /*error:INVALID_ASSIGNMENT*/ro;
1231 class A {} 1794 rn = rn;
1232 class B extends A {} 1795 rn = /*error:INVALID_ASSIGNMENT*/oo;
1233 class C extends B {} 1796 rn = /*error:INVALID_ASSIGNMENT*/nn;
1234 1797 rn = /*error:INVALID_ASSIGNMENT*/nnn;
1235 class Base { 1798
1236 B m1(B a); 1799 oo = /*warning:DOWN_CAST_COMPOSITE*/r;
1237 B m2(B a); 1800 oo = /*warning:DOWN_CAST_COMPOSITE*/o;
1238 B m3(B a); 1801 oo = /*error:INVALID_ASSIGNMENT*/n;
1239 B m4(B a); 1802 oo = /*warning:DOWN_CAST_COMPOSITE*/rr;
1240 B m5(B a); 1803 oo = /*warning:DOWN_CAST_COMPOSITE*/ro;
1241 B m6(B a); 1804 oo = /*error:INVALID_ASSIGNMENT*/rn;
1242 } 1805 oo = oo;
1243 1806 oo = /*error:INVALID_ASSIGNMENT*/nn;
1244 class Child extends Base { 1807 oo = /*error:INVALID_ASSIGNMENT*/nnn;
1245 /*severe:InvalidMethodOverride*/A m1(A value) {} 1808
1246 /*severe:InvalidMethodOverride*/C m2(C value) {} 1809 nn = /*error:INVALID_ASSIGNMENT*/r;
1247 /*severe:InvalidMethodOverride*/A m3(C value) {} 1810 nn = /*error:INVALID_ASSIGNMENT*/o;
1248 C m4(A value) {} 1811 nn = /*warning:DOWN_CAST_COMPOSITE*/n;
1249 m5(value) {} 1812 nn = /*error:INVALID_ASSIGNMENT*/rr;
1250 /*severe:InvalidMethodOverride*/dynamic m6(dynamic value) {} 1813 nn = /*error:INVALID_ASSIGNMENT*/ro;
1251 } 1814 nn = /*error:INVALID_ASSIGNMENT*/rn;
1252 ''' 1815 nn = /*error:INVALID_ASSIGNMENT*/oo;
1253 }); 1816 nn = nn;
1254 1817 nn = nnn;
1255 testChecker('unary operators', { 1818
1256 '/main.dart': ''' 1819 nnn = /*error:INVALID_ASSIGNMENT*/r;
1257 class A { 1820 nnn = /*error:INVALID_ASSIGNMENT*/o;
1258 A operator ~() {} 1821 nnn = /*warning:DOWN_CAST_COMPOSITE*/n;
1259 A operator +(int x) {} 1822 nnn = /*error:INVALID_ASSIGNMENT*/rr;
1260 A operator -(int x) {} 1823 nnn = /*error:INVALID_ASSIGNMENT*/ro;
1261 A operator -() {} 1824 nnn = /*error:INVALID_ASSIGNMENT*/rn;
1262 } 1825 nnn = /*error:INVALID_ASSIGNMENT*/oo;
1263 1826 nnn = /*warning:DOWN_CAST_COMPOSITE*/nn;
1264 foo() => new A(); 1827 nnn = nnn;
1265 1828 }
1266 test() { 1829 ''');
1267 A a = new A(); 1830 }
1268 var c = foo(); 1831
1269 1832 void test_functionTypingAndSubtyping_objectsWithCallMethods() {
1270 ~a; 1833 checkFile('''
1271 (/*info:DynamicInvoke*/~d); 1834 typedef int I2I(int x);
1272 1835 typedef num N2N(num x);
1273 !/*severe:StaticTypeError*/a; 1836 class A {
1274 !/*info:DynamicCast*/d; 1837 int call(int x) => x;
1275 1838 }
1276 -a; 1839 class B {
1277 (/*info:DynamicInvoke*/-d); 1840 num call(num x) => x;
1278 1841 }
1279 ++a; 1842 int i2i(int x) => x;
1280 --a; 1843 num n2n(num x) => x;
1281 (/*info:DynamicInvoke*/++d); 1844 void main() {
1282 (/*info:DynamicInvoke*/--d); 1845 {
1283 1846 I2I f;
1284 a++; 1847 f = new A();
1285 a--; 1848 f = /*error:INVALID_ASSIGNMENT*/new B();
1286 (/*info:DynamicInvoke*/d++); 1849 f = i2i;
1287 (/*info:DynamicInvoke*/d--); 1850 f = /*error:INVALID_ASSIGNMENT*/n2n;
1288 }''' 1851 f = /*info:UNNECESSARY_CAST,warning:DOWN_CAST_COMPOSITE*/i2i as Object;
1289 }); 1852 f = /*info:UNNECESSARY_CAST,warning:DOWN_CAST_COMPOSITE*/n2n as Function;
1290 1853 }
1291 testChecker('binary and index operators', { 1854 {
1292 '/main.dart': ''' 1855 N2N f;
1293 class A { 1856 f = /*error:INVALID_ASSIGNMENT*/new A();
1294 A operator *(B b) {} 1857 f = new B();
1295 A operator /(B b) {} 1858 f = /*error:INVALID_ASSIGNMENT*/i2i;
1296 A operator ~/(B b) {} 1859 f = n2n;
1297 A operator %(B b) {} 1860 f = /*info:UNNECESSARY_CAST,warning:DOWN_CAST_COMPOSITE*/i2i as Object;
1298 A operator +(B b) {} 1861 f = /*info:UNNECESSARY_CAST,warning:DOWN_CAST_COMPOSITE*/n2n as Function;
1299 A operator -(B b) {} 1862 }
1300 A operator <<(B b) {} 1863 {
1301 A operator >>(B b) {} 1864 A f;
1302 A operator &(B b) {} 1865 f = new A();
1303 A operator ^(B b) {} 1866 f = /*error:INVALID_ASSIGNMENT*/new B();
1304 A operator |(B b) {} 1867 f = /*error:INVALID_ASSIGNMENT*/i2i;
1305 A operator[](B b) {} 1868 f = /*error:INVALID_ASSIGNMENT*/n2n;
1306 } 1869 f = /*info:UNNECESSARY_CAST,info:DOWN_CAST_IMPLICIT*/i2i as Object;
1307 1870 f = /*info:UNNECESSARY_CAST,info:DOWN_CAST_IMPLICIT*/n2n as Function;
1308 class B { 1871 }
1309 A operator -(B b) {} 1872 {
1310 } 1873 B f;
1311 1874 f = /*error:INVALID_ASSIGNMENT*/new A();
1312 foo() => new A(); 1875 f = new B();
1313 1876 f = /*error:INVALID_ASSIGNMENT*/i2i;
1314 test() { 1877 f = /*error:INVALID_ASSIGNMENT*/n2n;
1315 A a = new A(); 1878 f = /*info:UNNECESSARY_CAST,info:DOWN_CAST_IMPLICIT*/i2i as Object;
1316 B b = new B(); 1879 f = /*info:UNNECESSARY_CAST,info:DOWN_CAST_IMPLICIT*/n2n as Function;
1317 var c = foo(); 1880 }
1318 a = a * b; 1881 {
1319 a = a * /*info:DynamicCast*/c; 1882 Function f;
1320 a = a / b; 1883 f = new A();
1321 a = a ~/ b; 1884 f = new B();
1322 a = a % b; 1885 f = i2i;
1323 a = a + b; 1886 f = n2n;
1324 a = a + /*severe:StaticTypeError*/a; 1887 f = /*info:UNNECESSARY_CAST,info:DOWN_CAST_IMPLICIT*/i2i as Object;
1325 a = a - b; 1888 f = /*info:UNNECESSARY_CAST*/n2n as Function;
1326 b = /*severe:StaticTypeError*/b - b; 1889 }
1327 a = a << b; 1890 }
1328 a = a >> b; 1891 ''');
1329 a = a & b; 1892 }
1330 a = a ^ b; 1893
1331 a = a | b; 1894 void test_functionTypingAndSubtyping_staticMethodVariance() {
1332 c = (/*info:DynamicInvoke*/c + b); 1895 checkFile('''
1333 1896 class A {}
1334 String x = 'hello'; 1897 class B extends A {}
1335 int y = 42; 1898
1336 x = x + x; 1899 class C {
1337 x = x + /*info:DynamicCast*/c; 1900 static A top(B x) => x;
1338 x = x + /*severe:StaticTypeError*/y; 1901 static B left(B x) => x;
1339 1902 static A right(A x) => x;
1340 bool p = true; 1903 static B bot(A x) => x as B;
1341 p = p && p; 1904 }
1342 p = p && /*info:DynamicCast*/c; 1905
1343 p = (/*info:DynamicCast*/c) && p; 1906 typedef T Function2<S, T>(S z);
1344 p = (/*info:DynamicCast*/c) && /*info:DynamicCast*/c; 1907
1345 p = (/*severe:StaticTypeError*/y) && p; 1908 void main() {
1346 p = c == y; 1909 {
1347 1910 Function2<B, A> f;
1348 a = a[b]; 1911 f = C.top;
1349 a = a[/*info:DynamicCast*/c]; 1912 f = C.left;
1350 c = (/*info:DynamicInvoke*/c[b]); 1913 f = C.right;
1351 a[/*severe:StaticTypeError*/y]; 1914 f = C.bot;
1352 } 1915 }
1353 ''' 1916 {
1354 }); 1917 Function2<B, B> f;
1355 1918 f = /*error:STATIC_TYPE_ERROR*/C.top;
1356 testChecker('compound assignments', { 1919 f = C.left;
1357 '/main.dart': ''' 1920 f = /*error:INVALID_ASSIGNMENT*/C.right;
1358 class A { 1921 f = C.bot;
1359 A operator *(B b) {} 1922 }
1360 A operator /(B b) {} 1923 {
1361 A operator ~/(B b) {} 1924 Function2<A, A> f;
1362 A operator %(B b) {} 1925 f = /*error:STATIC_TYPE_ERROR*/C.top;
1363 A operator +(B b) {} 1926 f = /*error:INVALID_ASSIGNMENT*/C.left;
1364 A operator -(B b) {} 1927 f = C.right;
1365 A operator <<(B b) {} 1928 f = C.bot;
1366 A operator >>(B b) {} 1929 }
1367 A operator &(B b) {} 1930 {
1368 A operator ^(B b) {} 1931 Function2<A, B> f;
1369 A operator |(B b) {} 1932 f = /*error:STATIC_TYPE_ERROR*/C.top;
1370 D operator [](B index) {} 1933 f = /*error:STATIC_TYPE_ERROR*/C.left;
1371 void operator []=(B index, D value) {} 1934 f = /*error:STATIC_TYPE_ERROR*/C.right;
1372 } 1935 f = C.bot;
1373 1936 }
1374 class B { 1937 }
1375 A operator -(B b) {} 1938 ''');
1376 } 1939 }
1377 1940
1378 class D { 1941 void test_functionTypingAndSubtyping_subtypeOfUniversalType() {
1379 D operator +(D d) {} 1942 checkFile('''
1380 } 1943 void main() {
1381 1944 nonGenericFn(x) => null;
1382 foo() => new A(); 1945 {
1383 1946 /*=R*/ f/*<P, R>*/(/*=P*/ p) => null;
1384 test() { 1947 /*=T*/ g/*<S, T>*/(/*=S*/ s) => null;
1385 int x = 0; 1948
1386 x += 5; 1949 var local = f;
1387 (/*severe:StaticTypeError*/x += 3.14); 1950 local = g; // valid
1388 1951
1389 double y = 0.0; 1952 // Non-generic function cannot subtype a generic one.
1390 y += 5; 1953 local = /*error:INVALID_ASSIGNMENT*/(x) => null;
1391 y += 3.14; 1954 local = /*error:INVALID_ASSIGNMENT*/nonGenericFn;
1392 1955 }
1393 num z = 0; 1956 {
1394 z += 5; 1957 Iterable/*<R>*/ f/*<P, R>*/(List/*<P>*/ p) => null;
1395 z += 3.14; 1958 List/*<T>*/ g/*<S, T>*/(Iterable/*<S>*/ s) => null;
1396 1959
1397 x = /*info:DownCastImplicit*/x + z; 1960 var local = f;
1398 x += /*info:DownCastImplicit*/z; 1961 local = g; // valid
1399 y = /*info:DownCastImplicit*/y + z; 1962
1400 y += /*info:DownCastImplicit*/z; 1963 var local2 = g;
1401 1964 local = local2;
1402 dynamic w = 42; 1965 local2 = /*error:STATIC_TYPE_ERROR*/f;
1403 x += /*info:DynamicCast*/w; 1966 local2 = /*warning:DOWN_CAST_COMPOSITE*/local;
1404 y += /*info:DynamicCast*/w; 1967
1405 z += /*info:DynamicCast*/w; 1968 // Non-generic function cannot subtype a generic one.
1406 1969 local = /*error:INVALID_ASSIGNMENT*/(x) => null;
1407 A a = new A(); 1970 local = /*error:INVALID_ASSIGNMENT*/nonGenericFn;
1408 B b = new B(); 1971 }
1409 var c = foo(); 1972 }
1410 a = a * b; 1973 ''');
1411 a *= b; 1974 }
1412 a *= /*info:DynamicCast*/c; 1975
1413 a /= b; 1976 void test_functionTypingAndSubtyping_uninferredClosure() {
1414 a ~/= b; 1977 checkFile('''
1415 a %= b; 1978 typedef num Num2Num(num x);
1416 a += b; 1979 void main() {
1417 a += /*severe:StaticTypeError*/a; 1980 Num2Num g = /*info:INFERRED_TYPE_CLOSURE,error:INVALID_ASSIGNMENT*/(int x) { r eturn x; };
1418 a -= b; 1981 print(g(42));
1419 (/*severe:StaticTypeError*/b -= b); 1982 }
1420 a <<= b; 1983 ''');
1421 a >>= b; 1984 }
1422 a &= b; 1985
1423 a ^= b; 1986 void test_functionTypingAndSubtyping_void() {
1424 a |= b; 1987 checkFile('''
1425 (/*info:DynamicInvoke*/c += b); 1988 class A {
1426 1989 void bar() => null;
1427 var d = new D(); 1990 void foo() => bar(); // allowed
1428 a[b] += d; 1991 }
1429 a[/*info:DynamicCast*/c] += d; 1992 ''');
1430 a[/*severe:StaticTypeError*/z] += d; 1993 }
1431 a[b] += /*info:DynamicCast*/c; 1994
1432 a[b] += /*severe:StaticTypeError*/z; 1995 void test_genericClassMethodOverride() {
1433 (/*info:DynamicInvoke*/(/*info:DynamicInvoke*/c[b]) += d); 1996 checkFile('''
1434 } 1997 class A {}
1435 ''' 1998 class B extends A {}
1436 }); 1999
1437 2000 class Base<T extends B> {
1438 testChecker('super call placement', { 2001 T foo() => null;
1439 '/main.dart': ''' 2002 }
1440 class Base { 2003
1441 var x; 2004 class Derived<S extends A> extends Base<B> {
1442 Base() : x = print('Base.1') { print('Base.2'); } 2005 /*error:INVALID_METHOD_OVERRIDE*/S foo() => null;
1443 } 2006 }
1444 2007
1445 class Derived extends Base { 2008 class Derived2<S extends B> extends Base<B> {
1446 var y, z; 2009 S foo() => null;
1447 Derived() 2010 }
1448 : y = print('Derived.1'), 2011 ''');
1449 /*severe:InvalidSuperInvocation*/super(), 2012 }
1450 z = print('Derived.2') { 2013
1451 print('Derived.3'); 2014 void test_genericFunctionWrongNumberOfArguments() {
1452 } 2015 checkFile(r'''
1453 } 2016 /*=T*/ foo/*<T>*/(/*=T*/ x, /*=T*/ y) => x;
1454 2017 /*=T*/ bar/*<T>*/({/*=T*/ x, /*=T*/ y}) => x;
1455 class Valid extends Base { 2018
1456 var y, z; 2019 main() {
1457 Valid() 2020 String x;
1458 : y = print('Valid.1'), 2021 // resolving these shouldn't crash.
1459 z = print('Valid.2'), 2022 foo/*error:EXTRA_POSITIONAL_ARGUMENTS*/(1, 2, 3);
1460 super() { 2023 x = foo/*error:EXTRA_POSITIONAL_ARGUMENTS*/('1', '2', '3');
1461 print('Valid.3'); 2024 foo/*error:NOT_ENOUGH_REQUIRED_ARGUMENTS*/(1);
1462 } 2025 x = foo/*error:NOT_ENOUGH_REQUIRED_ARGUMENTS*/('1');
1463 } 2026 x = /*error:COULD_NOT_INFER*/foo/*error:EXTRA_POSITIONAL_ARGUMENTS*/(/*error:A RGUMENT_TYPE_NOT_ASSIGNABLE*/1, /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/2, 3);
1464 2027 x = /*error:COULD_NOT_INFER*/foo/*error:NOT_ENOUGH_REQUIRED_ARGUMENTS*/(/*erro r:ARGUMENT_TYPE_NOT_ASSIGNABLE*/1);
1465 class AlsoValid extends Base { 2028
1466 AlsoValid() : super(); 2029 // named arguments
1467 } 2030 bar(y: 1, x: 2, /*error:UNDEFINED_NAMED_PARAMETER*/z: 3);
1468 2031 x = bar(/*error:UNDEFINED_NAMED_PARAMETER*/z: '1', x: '2', y: '3');
1469 main() => new Derived(); 2032 bar(y: 1);
1470 ''' 2033 x = bar(x: '1', /*error:UNDEFINED_NAMED_PARAMETER*/z: 42);
1471 }); 2034 x = /*error:COULD_NOT_INFER*/bar(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/y: 1, / *error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/x: 2, /*error:UNDEFINED_NAMED_PARAMETER*/z: 3);
1472 2035 x = /*error:COULD_NOT_INFER*/bar(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/x: 1);
1473 testChecker('for loop variable', { 2036 }
1474 '/main.dart': ''' 2037 ''');
1475 foo() { 2038 }
1476 for (int i = 0; i < 10; i++) { 2039
1477 i = /*severe:StaticTypeError*/"hi"; 2040 void test_genericMethodOverride() {
1478 } 2041 checkFile('''
1479 } 2042 class Future<T> {
1480 bar() { 2043 /*=S*/ then/*<S>*/(/*=S*/ onValue(T t)) => null;
1481 for (var i = 0; i < 10; i++) { 2044 }
1482 int j = i + 1; 2045
1483 } 2046 class DerivedFuture<T> extends Future<T> {
1484 } 2047 /*=S*/ then/*<S>*/(/*=S*/ onValue(T t)) => null;
1485 ''' 2048 }
1486 }); 2049
1487 2050 class DerivedFuture2<A> extends Future<A> {
1488 group('invalid overrides', () { 2051 /*=B*/ then/*<B>*/(/*=B*/ onValue(A a)) => null;
1489 testChecker('child override', { 2052 }
1490 '/main.dart': ''' 2053
1491 class A {} 2054 class DerivedFuture3<T> extends Future<T> {
1492 class B {} 2055 /*=S*/ then/*<S>*/(Object onValue(T t)) => null;
1493 2056 }
1494 class Base { 2057
1495 A f; 2058 class DerivedFuture4<A> extends Future<A> {
1496 } 2059 /*=B*/ then/*<B>*/(Object onValue(A a)) => null;
1497 2060 }
1498 class T1 extends Base { 2061 ''');
1499 /*severe:InvalidMethodOverride*/B get f => null; 2062 }
1500 } 2063
1501 2064 void test_getterGetterOverride() {
1502 class T2 extends Base { 2065 checkFile('''
1503 /*severe:InvalidMethodOverride*/set f(B b) => null; 2066 class A {}
1504 } 2067 class B extends A {}
1505 2068 class C extends B {}
1506 class T3 extends Base { 2069
1507 /*severe:InvalidMethodOverride*/final B f; 2070 abstract class Base {
1508 } 2071 B get f1;
1509 class T4 extends Base { 2072 B get f2;
1510 // two: one for the getter one for the setter. 2073 B get f3;
1511 /*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/B f; 2074 B get f4;
1512 } 2075 }
1513 ''' 2076
1514 }); 2077 class Child extends Base {
1515 2078 /*error:INVALID_METHOD_OVERRIDE*/A get f1 => null;
1516 testChecker('child override 2', { 2079 C get f2 => null;
1517 '/main.dart': ''' 2080 get f3 => null;
1518 class A {} 2081 /*error:INVALID_METHOD_OVERRIDE*/dynamic get f4 => null;
1519 class B {} 2082 }
1520 2083 ''');
1521 class Base { 2084 }
1522 m(A a) {} 2085
1523 } 2086 void test_getterOverride_fuzzyArrows() {
1524 2087 checkFile('''
1525 class Test extends Base { 2088 typedef void ToVoid<T>(T x);
1526 /*severe:InvalidMethodOverride*/m(B a) {} 2089
1527 } 2090 class F {
1528 ''' 2091 ToVoid<dynamic> get f => null;
1529 }); 2092 ToVoid<int> get g => null;
1530 testChecker('grandchild override', { 2093 }
1531 '/main.dart': ''' 2094
1532 class A {} 2095 class G extends F {
1533 class B {} 2096 ToVoid<int> get f => null;
1534 2097 /*error:INVALID_METHOD_OVERRIDE*/ToVoid<dynamic> get g => null;
1535 class Grandparent { 2098 }
1536 m(A a) {} 2099
1537 } 2100 class H implements F {
1538 class Parent extends Grandparent { 2101 ToVoid<int> get f => null;
1539 } 2102 /*error:INVALID_METHOD_OVERRIDE*/ToVoid<dynamic> get g => null;
1540 2103 }
1541 class Test extends Parent { 2104 ''');
1542 /*severe:InvalidMethodOverride*/m(B a) {} 2105 }
1543 } 2106
1544 ''' 2107 void test_ifForDoWhileStatementsUseBooleanConversion() {
1545 }); 2108 checkFile('''
1546 2109 main() {
1547 testChecker('double override', { 2110 dynamic dyn = 42;
1548 '/main.dart': ''' 2111 Object obj = 42;
1549 class A {} 2112 int i = 42;
1550 class B {} 2113 bool b = false;
1551 2114
1552 class Grandparent { 2115 if (b) {}
1553 m(A a) {} 2116 if (/*info:DYNAMIC_CAST*/dyn) {}
1554 } 2117 if (/*info:DOWN_CAST_IMPLICIT*/obj) {}
1555 class Parent extends Grandparent { 2118 if (/*error:NON_BOOL_CONDITION*/i) {}
1556 m(A a) {} 2119
1557 } 2120 while (b) {}
1558 2121 while (/*info:DYNAMIC_CAST*/dyn) {}
1559 class Test extends Parent { 2122 while (/*info:DOWN_CAST_IMPLICIT*/obj) {}
1560 // Reported only once 2123 while (/*error:NON_BOOL_CONDITION*/i) {}
1561 /*severe:InvalidMethodOverride*/m(B a) {} 2124
1562 } 2125 do {} while (b);
1563 ''' 2126 do {} while (/*info:DYNAMIC_CAST*/dyn);
1564 }); 2127 do {} while (/*info:DOWN_CAST_IMPLICIT*/obj);
1565 2128 do {} while (/*error:NON_BOOL_CONDITION*/i);
1566 testChecker('double override 2', { 2129
1567 '/main.dart': ''' 2130 for (;b;) {}
1568 class A {} 2131 for (;/*info:DYNAMIC_CAST*/dyn;) {}
1569 class B {} 2132 for (;/*info:DOWN_CAST_IMPLICIT*/obj;) {}
1570 2133 for (;/*error:NON_BOOL_CONDITION*/i;) {}
1571 class Grandparent { 2134 }
1572 m(A a) {} 2135 ''');
1573 } 2136 }
1574 class Parent extends Grandparent { 2137
1575 /*severe:InvalidMethodOverride*/m(B a) {} 2138 void test_implicitCasts() {
1576 } 2139 addFile('num n; int i = /*info:ASSIGNMENT_CAST*/n;');
1577 2140 check();
1578 class Test extends Parent { 2141 // TODO(jmesserly): should not be emitting the hint as well as the error.
1579 m(B a) {} 2142 // It is a "strong mode hint" however, so it will not be user visible.
1580 } 2143 addFile(
1581 ''' 2144 'num n; int i = /*info:ASSIGNMENT_CAST,error:INVALID_ASSIGNMENT*/n;');
1582 }); 2145 check(implicitCasts: false);
1583 2146 }
1584 testChecker('mixin override to base', { 2147
1585 '/main.dart': ''' 2148 void test_implicitCasts_genericMethods() {
1586 class A {} 2149 addFile('var x = <String>[].map((x) => "");');
1587 class B {} 2150 check(implicitCasts: false);
1588 2151 }
1589 class Base { 2152
1590 m(A a) {} 2153 void test_implicitCasts_numericOps() {
1591 } 2154 // Regression test for https://github.com/dart-lang/sdk/issues/26912
1592 2155 addFile(r'''
1593 class M1 { 2156 void f() {
1594 m(B a) {} 2157 int x = 0;
1595 } 2158 int y = 0;
1596 2159 x += y;
1597 class M2 {} 2160 }
1598 2161 ''');
1599 class T1 extends Base with /*severe:InvalidMethodOverride*/M1 {} 2162 check(implicitCasts: false);
1600 class T2 extends Base with /*severe:InvalidMethodOverride*/M1, M2 {} 2163 }
1601 class T3 extends Base with M2, /*severe:InvalidMethodOverride*/M1 {} 2164
1602 ''' 2165 void test_implicitDynamic_field() {
1603 }); 2166 addFile(r'''
1604 2167 class C {
1605 testChecker('mixin override to mixin', { 2168 var /*error:IMPLICIT_DYNAMIC_FIELD*/x0;
1606 '/main.dart': ''' 2169 var /*error:IMPLICIT_DYNAMIC_FIELD*/x1 = (<dynamic>[])[0];
1607 class A {} 2170 var /*error:IMPLICIT_DYNAMIC_FIELD*/x2,
1608 class B {} 2171 x3 = 42,
1609 2172 /*error:IMPLICIT_DYNAMIC_FIELD*/x4;
1610 class Base { 2173 dynamic y0;
1611 } 2174 dynamic y1 = (<dynamic>[])[0];
1612 2175 }
1613 class M1 { 2176 ''');
1614 m(B a) {} 2177 check(implicitDynamic: false);
1615 } 2178 }
1616 2179
1617 class M2 { 2180 void test_implicitDynamic_function() {
1618 m(A a) {} 2181 addFile(r'''
1619 } 2182 /*=T*/ a/*<T>*/(/*=T*/ t) => t;
1620 2183 /*=T*/ b/*<T>*/() => null;
1621 class T1 extends Base with M1, /*severe:InvalidMethodOverride*/M2 {} 2184
1622 ''' 2185 void main/*<S>*/() {
1623 }); 2186 dynamic d;
1624 2187 int i;
2188 /*error:IMPLICIT_DYNAMIC_FUNCTION*/a(d);
2189 a(42);
2190 /*error:IMPLICIT_DYNAMIC_FUNCTION*/b();
2191 d = /*error:IMPLICIT_DYNAMIC_FUNCTION*/b();
2192 i = b();
2193
2194 void f/*<T>*/(/*=T*/ t) {};
2195 /*=T*/ g/*<T>*/() => null;
2196
2197 /*error:IMPLICIT_DYNAMIC_FUNCTION*/f(d);
2198 f(42);
2199 /*error:IMPLICIT_DYNAMIC_FUNCTION*/g();
2200 d = /*error:IMPLICIT_DYNAMIC_FUNCTION*/g();
2201 i = g();
2202
2203 /*error:IMPLICIT_DYNAMIC_INVOKE*/(/*<T>*/(/*=T*/ t) => t)(d);
2204 (/*<T>*/(/*=T*/ t) => t)(42);
2205 (/*<T>*/() => /*info:UNNECESSARY_CAST*/null as dynamic/*=T*/)/*<int>*/();
2206 }
2207 ''');
2208 check(implicitDynamic: false);
2209 }
2210
2211 void test_implicitDynamic_listLiteral() {
2212 addFile(r'''
2213
2214 var l0 = /*error:IMPLICIT_DYNAMIC_LIST_LITERAL*/[];
2215 List l1 = /*error:IMPLICIT_DYNAMIC_LIST_LITERAL*/[];
2216 List<dynamic> l2 = /*error:IMPLICIT_DYNAMIC_LIST_LITERAL*/[];
2217 dynamic d = 42;
2218 var l3 = /*error:IMPLICIT_DYNAMIC_LIST_LITERAL*/[d, d];
2219
2220 var l4 = <dynamic>[];
2221 var l5 = <int>[];
2222 List<int> l6 = /*info:INFERRED_TYPE_LITERAL*/[];
2223 var l7 = /*info:INFERRED_TYPE_LITERAL*/[42];
2224 ''');
2225 check(implicitDynamic: false);
2226 }
2227
2228 void test_implicitDynamic_mapLiteral() {
2229 addFile(r'''
2230 var m0 = /*error:IMPLICIT_DYNAMIC_MAP_LITERAL*/{};
2231 Map m1 = /*error:IMPLICIT_DYNAMIC_MAP_LITERAL*/{};
2232 Map<dynamic, dynamic> m2 = /*error:IMPLICIT_DYNAMIC_MAP_LITERAL*/{};
2233 dynamic d = 42;
2234 var m3 = /*error:IMPLICIT_DYNAMIC_MAP_LITERAL*/{d: d};
2235 var m4 = /*info:INFERRED_TYPE_LITERAL,error:IMPLICIT_DYNAMIC_MAP_LITERAL*/{'x': d, 'y': d};
2236 var m5 = /*info:INFERRED_TYPE_LITERAL,error:IMPLICIT_DYNAMIC_MAP_LITERAL*/{d: 'x '};
2237
2238 var m6 = <dynamic, dynamic>{};
2239 var m7 = <String, String>{};
2240 Map<String, String> m8 = /*info:INFERRED_TYPE_LITERAL*/{};
2241 var m9 = /*info:INFERRED_TYPE_LITERAL*/{'hi': 'there'};
2242 ''');
2243 check(implicitDynamic: false);
2244 }
2245
2246 void test_implicitDynamic_method() {
2247 addFile(r'''
2248 class C {
2249 /*=T*/ m/*<T>*/(/*=T*/ s) => s;
2250 /*=T*/ n/*<T>*/() => null;
2251 }
2252 class D<E> {
2253 /*=T*/ m/*<T>*/(/*=T*/ s) => s;
2254 /*=T*/ n/*<T>*/() => null;
2255 }
2256 void f() {
2257 dynamic d;
2258 int i;
2259 new C()./*error:IMPLICIT_DYNAMIC_METHOD*/m(d);
2260 new C().m(42);
2261 new C()./*error:IMPLICIT_DYNAMIC_METHOD*/n();
2262 d = new C()./*error:IMPLICIT_DYNAMIC_METHOD*/n();
2263 i = new C().n();
2264
2265 new D<int>()./*error:IMPLICIT_DYNAMIC_METHOD*/m(d);
2266 new D<int>().m(42);
2267 new D<int>()./*error:IMPLICIT_DYNAMIC_METHOD*/n();
2268 d = new D<int>()./*error:IMPLICIT_DYNAMIC_METHOD*/n();
2269 i = new D<int>().n();
2270 }
2271 ''');
2272 check(implicitDynamic: false);
2273 }
2274
2275 void test_implicitDynamic_parameter() {
2276 addFile(r'''
2277 const dynamic DYNAMIC_VALUE = 42;
2278
2279 // simple formal
2280 void f0(/*error:IMPLICIT_DYNAMIC_PARAMETER*/x) {}
2281 void f1(dynamic x) {}
2282
2283 // default formal
2284 void df0([/*error:IMPLICIT_DYNAMIC_PARAMETER*/x = DYNAMIC_VALUE]) {}
2285 void df1([dynamic x = DYNAMIC_VALUE]) {}
2286
2287 // https://github.com/dart-lang/sdk/issues/25794
2288 void df2([/*error:IMPLICIT_DYNAMIC_PARAMETER*/x = 42]) {}
2289
2290 // default formal (named)
2291 void nf0({/*error:IMPLICIT_DYNAMIC_PARAMETER*/x: DYNAMIC_VALUE}) {}
2292 void nf1({dynamic x: DYNAMIC_VALUE}) {}
2293
2294 // https://github.com/dart-lang/sdk/issues/25794
2295 void nf2({/*error:IMPLICIT_DYNAMIC_PARAMETER*/x: 42}) {}
2296
2297 // field formal
2298 class C {
2299 var /*error:IMPLICIT_DYNAMIC_FIELD*/x;
2300 C(this.x);
2301 }
2302
2303 // function typed formal
2304 void ftf0(void x(/*error:IMPLICIT_DYNAMIC_PARAMETER*/y)) {}
2305 void ftf1(void x(int y)) {}
2306 ''');
2307 check(implicitDynamic: false);
2308 }
2309
2310 void test_implicitDynamic_return() {
2311 addFile(r'''
2312 // function
2313 /*error:IMPLICIT_DYNAMIC_RETURN*/f0() {}
2314 dynamic f1() { return 42; }
2315
2316 // nested function
2317 void main() {
2318 /*error:IMPLICIT_DYNAMIC_RETURN*/g0() {}
2319 dynamic g1() { return 42; }
2320 }
2321
2322 // methods
2323 class B {
2324 int m1() => 42;
2325 }
2326 class C extends B {
2327 /*error:IMPLICIT_DYNAMIC_RETURN*/m0() => 123;
2328 m1() => 123;
2329 dynamic m2() => 'hi';
2330 }
2331
2332 // accessors
2333 set x(int value) {}
2334 /*error:IMPLICIT_DYNAMIC_RETURN*/get y0 => 42;
2335 dynamic get y1 => 42;
2336
2337 // function typed formals
2338 void ftf0(/*error:IMPLICIT_DYNAMIC_RETURN*/f(int x)) {}
2339 void ftf1(dynamic f(int x)) {}
2340
2341 // function expressions
2342 var fe0 = (int x) => x as dynamic;
2343 var fe1 = (int x) => x;
2344 ''');
2345 check(implicitDynamic: false);
2346 }
2347
2348 void test_implicitDynamic_type() {
2349 addFile(r'''
2350 class C<T> {}
2351 class M1<T extends /*error:IMPLICIT_DYNAMIC_TYPE*/List> {}
2352 class M2<T> {}
2353 class I<T> {}
2354 class D<T, S> extends /*error:IMPLICIT_DYNAMIC_TYPE*/C
2355 with M1, /*error:IMPLICIT_DYNAMIC_TYPE*/M2
2356 implements /*error:IMPLICIT_DYNAMIC_TYPE*/I {}
2357
2358 C f(D d) {
2359 D x = new /*error:IMPLICIT_DYNAMIC_TYPE*/D();
2360 D<int, dynamic> y = /*info:INFERRED_TYPE_ALLOCATION*/new /*error:IMPLICIT_DYNA MIC_TYPE*/D();
2361 D<dynamic, int> z = /*info:INFERRED_TYPE_ALLOCATION*/new /*error:IMPLICIT_DYNA MIC_TYPE*/D();
2362 return new /*error:IMPLICIT_DYNAMIC_TYPE*/C();
2363 }
2364
2365 class A<T extends num> {}
2366 class N1<T extends List<int>> {}
2367 class N2<T extends Object> {}
2368 class J<T extends Object> {}
2369 class B<T extends Object> extends A with N1, N2 implements J {}
2370 A g(B b) {
2371 B y = /*info:INFERRED_TYPE_ALLOCATION*/new B();
2372 return /*info:INFERRED_TYPE_ALLOCATION*/new A();
2373 }
2374 ''');
2375 check(implicitDynamic: false);
2376 }
2377
2378 void test_implicitDynamic_variable() {
2379 addFile(r'''
2380 var /*error:IMPLICIT_DYNAMIC_VARIABLE*/x0;
2381 var /*error:IMPLICIT_DYNAMIC_VARIABLE*/x1 = (<dynamic>[])[0];
2382 var /*error:IMPLICIT_DYNAMIC_VARIABLE*/x2,
2383 x3 = 42,
2384 /*error:IMPLICIT_DYNAMIC_VARIABLE*/x4;
2385 dynamic y0;
2386 dynamic y1 = (<dynamic>[])[0];
2387 ''');
2388 check(implicitDynamic: false);
2389 }
2390
2391 void test_invalidOverrides_baseClassOverrideToChildInterface() {
2392 checkFile('''
2393 class A {}
2394 class B {}
2395
2396 abstract class I {
2397 m(A a);
2398 }
2399
2400 class Base {
2401 m(B a) {}
2402 }
2403
2404 class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1
2405 /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base implements I {}
2406 ''');
2407 }
2408
2409 void test_invalidOverrides_childOverride() {
2410 checkFile('''
2411 class A {}
2412 class B {}
2413
2414 class Base {
2415 A f;
2416 }
2417
2418 class T1 extends Base {
2419 /*warning:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, error:INVALID_FIE LD_OVERRIDE, error:INVALID_METHOD_OVERRIDE*/B get f => null;
2420 }
2421
2422 class T2 extends Base {
2423 /*warning:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, error:INVALID_FIE LD_OVERRIDE, error:INVALID_METHOD_OVERRIDE*/set f(
2424 B b) => null;
2425 }
2426
2427 class T3 extends Base {
2428 /*error:INVALID_FIELD_OVERRIDE, error:INVALID_METHOD_OVERRIDE*/final B
2429 /*warning:FINAL_NOT_INITIALIZED*/f;
2430 }
2431 class T4 extends Base {
2432 // two: one for the getter one for the setter.
2433 /*error:INVALID_FIELD_OVERRIDE, error:INVALID_METHOD_OVERRIDE, error:INVALID_M ETHOD_OVERRIDE*/B f;
2434 }
2435
2436 class /*error:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/T5 implements Bas e {
2437 /*warning:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, error:INVALID_MET HOD_OVERRIDE*/B get f => null;
2438 }
2439
2440 class /*error:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/T6 implements Bas e {
2441 /*warning:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, error:INVALID_MET HOD_OVERRIDE*/set f(B b) => null;
2442 }
2443
2444 class /*error:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/T7 implements Bas e {
2445 /*error:INVALID_METHOD_OVERRIDE*/final B f = null;
2446 }
2447 class T8 implements Base {
2448 // two: one for the getter one for the setter.
2449 /*error:INVALID_METHOD_OVERRIDE, error:INVALID_METHOD_OVERRIDE*/B f;
2450 }
2451 ''');
2452 }
2453
2454 void test_invalidOverrides_childOverride2() {
2455 checkFile('''
2456 class A {}
2457 class B {}
2458
2459 class Base {
2460 m(A a) {}
2461 }
2462
2463 class Test extends Base {
2464 /*error:INVALID_METHOD_OVERRIDE*/m(B a) {}
2465 }
2466 ''');
2467 }
2468
2469 void test_invalidOverrides_classOverrideOfInterface() {
2470 checkFile('''
2471 class A {}
2472 class B {}
2473
2474 abstract class I {
2475 m(A a);
2476 }
2477
2478 class T1 implements I {
2479 /*error:INVALID_METHOD_OVERRIDE*/m(B a) {}
2480 }
2481 ''');
2482 }
2483
2484 void test_invalidOverrides_doubleOverride() {
2485 checkFile('''
2486 class A {}
2487 class B {}
2488
2489 class Grandparent {
2490 m(A a) {}
2491 }
2492 class Parent extends Grandparent {
2493 m(A a) {}
2494 }
2495
2496 class Test extends Parent {
2497 // Reported only once
2498 /*error:INVALID_METHOD_OVERRIDE*/m(B a) {}
2499 }
2500 ''');
2501 }
2502
2503 void test_invalidOverrides_doubleOverride2() {
2504 checkFile('''
2505 class A {}
2506 class B {}
2507
2508 class Grandparent {
2509 m(A a) {}
2510 }
2511 class Parent extends Grandparent {
2512 /*error:INVALID_METHOD_OVERRIDE*/m(B a) {}
2513 }
2514
2515 class Test extends Parent {
2516 m(B a) {}
2517 }
2518 ''');
2519 }
2520
2521 void test_invalidOverrides_grandChildOverride() {
2522 checkFile('''
2523 class A {}
2524 class B {}
2525
2526 class Grandparent {
2527 m(A a) {}
2528 int x;
2529 }
2530 class Parent extends Grandparent {
2531 }
2532
2533 class Test extends Parent {
2534 /*error:INVALID_METHOD_OVERRIDE*/m(B a) {}
2535 /*error:INVALID_FIELD_OVERRIDE*/int x;
2536 }
2537 ''');
2538 }
2539
2540 void test_invalidOverrides_mixinOverrideOfInterface() {
2541 checkFile('''
2542 class A {}
2543 class B {}
2544
2545 abstract class I {
2546 m(A a);
2547 }
2548
2549 class M {
2550 m(B a) {}
2551 }
2552
2553 class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1
2554 extends Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M
2555 implements I {}
2556 ''');
2557 }
2558
2559 void test_invalidOverrides_mixinOverrideToBase() {
2560 checkFile('''
2561 class A {}
2562 class B {}
2563
2564 class Base {
2565 m(A a) {}
2566 int x;
2567 }
2568
2569 class M1 {
2570 m(B a) {}
2571 }
2572
2573 class M2 {
2574 int x;
2575 }
2576
2577 class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
2578 with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M1 {}
2579 class /*error:INCONSISTENT_METHOD_INHERITANCE*/T2 extends Base
2580 with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M1, /*error:INVALID_FIELD_O VERRIDE*/M2 {}
2581 class /*error:INCONSISTENT_METHOD_INHERITANCE*/T3 extends Base
2582 with /*error:INVALID_FIELD_OVERRIDE*/M2, /*error:INVALID_METHOD_OVERRIDE_FRO M_MIXIN*/M1 {}
2583 ''');
2584 }
2585
2586 void test_invalidOverrides_mixinOverrideToMixin() {
2587 checkFile('''
2588 class A {}
2589 class B {}
2590
2591 class Base {
2592 }
2593
2594 class M1 {
2595 m(B a) {}
2596 int x;
2597 }
2598
2599 class M2 {
2600 m(A a) {}
2601 int x;
2602 }
2603
2604 class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
2605 with M1,
2606 /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN,error:INVALID_FIELD_OVERRIDE*/M2 {}
2607 ''');
2608 }
2609
2610 void test_invalidOverrides_noDuplicateMixinOverride() {
1625 // This is a regression test for a bug in an earlier implementation were 2611 // 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, 2612 // names were hiding errors if the first mixin override looked correct,
1627 // but subsequent ones did not. 2613 // but subsequent ones did not.
1628 testChecker('no duplicate mixin override', { 2614 checkFile('''
1629 '/main.dart': ''' 2615 class A {}
1630 class A {} 2616 class B {}
1631 class B {} 2617
1632 2618 class Base {
1633 class Base { 2619 m(A a) {}
1634 m(A a) {} 2620 }
1635 } 2621
1636 2622 class M1 {
1637 class M1 { 2623 m(A a) {}
1638 m(A a) {} 2624 }
1639 } 2625
1640 2626 class M2 {
1641 class M2 { 2627 m(B a) {}
1642 m(B a) {} 2628 }
1643 } 2629
1644 2630 class M3 {
1645 class M3 { 2631 m(B a) {}
1646 m(B a) {} 2632 }
1647 } 2633
1648 2634 class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
1649 class T1 extends Base 2635 with M1, /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M2, M3 {}
1650 with M1, /*severe:InvalidMethodOverride*/M2, M3 {} 2636 ''');
1651 ''' 2637 }
1652 }); 2638
1653 2639 void
1654 testChecker('class override of interface', { 2640 test_invalidOverrides_noErrorsIfSubclassCorrectlyOverrideBaseAndInterface( ) {
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 2641 // This is a case were it is incorrect to say that the base class
1707 // incorrectly overrides the interface. 2642 // incorrectly overrides the interface.
1708 testChecker( 2643 checkFile('''
1709 'no errors if subclass correctly overrides base and interface', { 2644 class A {}
1710 '/main.dart': ''' 2645 class B {}
1711 class A {} 2646
1712 class B {} 2647 class Base {
1713 2648 m(A a) {}
1714 class Base { 2649 }
1715 m(A a) {} 2650
1716 } 2651 class I1 {
1717 2652 m(B a) {}
1718 class I1 { 2653 }
1719 m(B a) {} 2654
1720 } 2655 class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1
1721 2656 /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base
1722 class T1 /*severe:InvalidMethodOverride*/extends Base 2657 implements I1 {}
1723 implements I1 {} 2658
1724 2659 class T2 extends Base implements I1 {
1725 class T2 extends Base implements I1 { 2660 m(a) {}
1726 /*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/m(a ) {} 2661 }
1727 } 2662
1728 2663 class /*error:INCONSISTENT_METHOD_INHERITANCE*/T3
1729 class T3 extends Object with /*severe:InvalidMethodOverride*/Base 2664 extends Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/Base
1730 implements I1 {} 2665 implements I1 {}
1731 2666
1732 class T4 extends Object with Base implements I1 { 2667 class T4 extends Object with Base implements I1 {
1733 /*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/m(a ) {} 2668 m(a) {}
1734 } 2669 }
1735 ''' 2670 ''');
1736 }); 2671 }
1737 }); 2672
1738 2673 void test_invalidRuntimeChecks() {
1739 group('class override of grand interface', () { 2674 checkFile('''
1740 testChecker('interface of interface of child', { 2675 typedef int I2I(int x);
1741 '/main.dart': ''' 2676 typedef int D2I(x);
1742 class A {} 2677 typedef int II2I(int x, int y);
1743 class B {} 2678 typedef int DI2I(x, int y);
1744 2679 typedef int ID2I(int x, y);
1745 abstract class I1 { 2680 typedef int DD2I(x, y);
1746 m(A a); 2681
1747 } 2682 typedef I2D(int x);
1748 abstract class I2 implements I1 {} 2683 typedef D2D(x);
1749 2684 typedef II2D(int x, int y);
1750 class T1 implements I2 { 2685 typedef DI2D(x, int y);
1751 /*severe:InvalidMethodOverride*/m(B a) {} 2686 typedef ID2D(int x, y);
1752 } 2687 typedef DD2D(x, y);
1753 ''' 2688
1754 }); 2689 int foo(int x) => x;
1755 testChecker('superclass of interface of child', { 2690 int bar(int x, int y) => x + y;
1756 '/main.dart': ''' 2691
1757 class A {} 2692 void main() {
1758 class B {} 2693 bool b;
1759 2694 b = /*info:NON_GROUND_TYPE_CHECK_INFO*/foo is I2I;
1760 abstract class I1 { 2695 b = /*info:NON_GROUND_TYPE_CHECK_INFO*/foo is D2I;
1761 m(A a); 2696 b = /*info:NON_GROUND_TYPE_CHECK_INFO*/foo is I2D;
1762 } 2697 b = foo is D2D;
1763 abstract class I2 extends I1 {} 2698
1764 2699 b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is II2I;
1765 class T1 implements I2 { 2700 b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is DI2I;
1766 /*severe:InvalidMethodOverride*/m(B a) {} 2701 b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is ID2I;
1767 } 2702 b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is II2D;
1768 ''' 2703 b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is DD2I;
1769 }); 2704 b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is DI2D;
1770 testChecker('mixin of interface of child', { 2705 b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is ID2D;
1771 '/main.dart': ''' 2706 b = bar is DD2D;
1772 class A {} 2707
1773 class B {} 2708 // For as, the validity of checks is deferred to runtime.
1774 2709 Function f;
1775 abstract class M1 { 2710 f = /*info:UNNECESSARY_CAST*/foo as I2I;
1776 m(A a); 2711 f = /*info:UNNECESSARY_CAST*/foo as D2I;
1777 } 2712 f = /*info:UNNECESSARY_CAST*/foo as I2D;
1778 abstract class I2 extends Object with M1 {} 2713 f = /*info:UNNECESSARY_CAST*/foo as D2D;
1779 2714
1780 class T1 implements I2 { 2715 f = /*info:UNNECESSARY_CAST*/bar as II2I;
1781 /*severe:InvalidMethodOverride*/m(B a) {} 2716 f = /*info:UNNECESSARY_CAST*/bar as DI2I;
1782 } 2717 f = /*info:UNNECESSARY_CAST*/bar as ID2I;
1783 ''' 2718 f = /*info:UNNECESSARY_CAST*/bar as II2D;
1784 }); 2719 f = /*info:UNNECESSARY_CAST*/bar as DD2I;
1785 testChecker('interface of abstract superclass', { 2720 f = /*info:UNNECESSARY_CAST*/bar as DI2D;
1786 '/main.dart': ''' 2721 f = /*info:UNNECESSARY_CAST*/bar as ID2D;
1787 class A {} 2722 f = /*info:UNNECESSARY_CAST*/bar as DD2D;
1788 class B {} 2723 }
1789 2724 ''');
1790 abstract class I1 { 2725 }
1791 m(A a); 2726
1792 } 2727 void test_leastUpperBounds() {
1793 abstract class Base implements I1 {} 2728 checkFile('''
1794 2729 typedef T Returns<T>();
1795 class T1 extends Base { 2730
1796 /*severe:InvalidMethodOverride*/m(B a) {} 2731 // regression test for https://github.com/dart-lang/sdk/issues/26094
1797 } 2732 class A <S extends Returns<S>, T extends Returns<T>> {
1798 ''' 2733 int test(bool b) {
1799 }); 2734 S s;
1800 testChecker('interface of concrete superclass', { 2735 T t;
1801 '/main.dart': ''' 2736 if (b) {
1802 class A {} 2737 return /*error:RETURN_OF_INVALID_TYPE*/b ? s : t;
1803 class B {} 2738 } else {
1804 2739 return /*error:RETURN_OF_INVALID_TYPE*/s ?? t;
1805 abstract class I1 { 2740 }
1806 m(A a); 2741 }
1807 } 2742 }
1808 2743
1809 // See issue #25 2744 class B<S, T extends S> {
1810 /*pass should be warning:AnalyzerError*/class Base implements I1 { 2745 T t;
1811 } 2746 S s;
1812 2747 int test(bool b) {
1813 class T1 extends Base { 2748 return /*error:RETURN_OF_INVALID_TYPE*/b ? t : s;
1814 // not reported technically because if the class is concrete, 2749 }
1815 // it should implement all its interfaces and hence it is 2750 }
1816 // sufficient to check overrides against it. 2751
1817 m(B a) {} 2752 class C {
1818 } 2753 // Check that the least upper bound of two types with the same
1819 ''' 2754 // class but different type arguments produces the pointwise
1820 }); 2755 // least upper bound of the type arguments
1821 }); 2756 int test1(bool b) {
1822 2757 List<int> li;
1823 group('mixin override of grand interface', () { 2758 List<double> ld;
1824 testChecker('interface of interface of child', { 2759 return /*error:RETURN_OF_INVALID_TYPE*/b ? li : ld;
1825 '/main.dart': ''' 2760 }
1826 class A {} 2761 // TODO(leafp): This case isn't handled yet. This test checks
1827 class B {} 2762 // the case where two related classes are instantiated with related
1828 2763 // but different types.
1829 abstract class I1 { 2764 Iterable<num> test2(bool b) {
1830 m(A a); 2765 List<int> li;
1831 } 2766 Iterable<double> id;
1832 abstract class I2 implements I1 {} 2767 int x =
1833 2768 /*info:ASSIGNMENT_CAST should be error:INVALID_ASSIGNMENT*/
1834 class M { 2769 b ? li : id;
1835 m(B a) {} 2770 return /*warning:DOWN_CAST_COMPOSITE should be pass*/b ? li : id;
1836 } 2771 }
1837 2772 }
1838 class T1 extends Object with /*severe:InvalidMethodOverride*/M 2773 ''');
1839 implements I2 { 2774 }
1840 } 2775
1841 ''' 2776 void test_leastUpperBounds_fuzzyArrows() {
1842 }); 2777 checkFile(r'''
1843 testChecker('superclass of interface of child', { 2778 typedef String TakesA<T>(T item);
1844 '/main.dart': ''' 2779
1845 class A {} 2780 void main() {
1846 class B {} 2781 TakesA<int> f;
1847 2782 TakesA<dynamic> g;
1848 abstract class I1 { 2783 TakesA<String> h;
1849 m(A a); 2784 g = h;
1850 } 2785 f = /*warning:DOWN_CAST_COMPOSITE*/f ?? g;
1851 abstract class I2 extends I1 {} 2786 }
1852 2787 ''');
1853 class M { 2788 }
1854 m(B a) {} 2789
1855 } 2790 void test_loadLibrary() {
1856 2791 addFile('''library lib1;''', name: '/lib1.dart');
1857 class T1 extends Object with /*severe:InvalidMethodOverride*/M 2792 checkFile(r'''
1858 implements I2 { 2793 import 'lib1.dart' deferred as lib1;
1859 } 2794 import 'dart:async' show Future;
1860 ''' 2795 main() {
1861 }); 2796 Future f = lib1.loadLibrary();
1862 testChecker('mixin of interface of child', { 2797 }''');
1863 '/main.dart': ''' 2798 }
1864 class A {} 2799
1865 class B {} 2800 void test_methodOverride() {
1866 2801 checkFile('''
1867 abstract class M1 { 2802 class A {}
1868 m(A a); 2803 class B extends A {}
1869 } 2804 class C extends B {}
1870 abstract class I2 extends Object with M1 {} 2805
1871 2806 class Base {
1872 class M { 2807 B m1(B a) => null;
1873 m(B a) {} 2808 B m2(B a) => null;
1874 } 2809 B m3(B a) => null;
1875 2810 B m4(B a) => null;
1876 class T1 extends Object with /*severe:InvalidMethodOverride*/M 2811 B m5(B a) => null;
1877 implements I2 { 2812 B m6(B a) => null;
1878 } 2813 }
1879 ''' 2814
1880 }); 2815 class Child extends Base {
1881 testChecker('interface of abstract superclass', { 2816 /*error:INVALID_METHOD_OVERRIDE*/A m1(A value) => null;
1882 '/main.dart': ''' 2817 /*error:INVALID_METHOD_OVERRIDE*/C m2(C value) => null;
1883 class A {} 2818 /*error:INVALID_METHOD_OVERRIDE*/A m3(C value) => null;
1884 class B {} 2819 C m4(A value) => null;
1885 2820 m5(value) => null;
1886 abstract class I1 { 2821 /*error:INVALID_METHOD_OVERRIDE*/dynamic m6(dynamic value) => null;
1887 m(A a); 2822 }
1888 } 2823 ''');
1889 abstract class Base implements I1 {} 2824 }
1890 2825
1891 class M { 2826 void test_methodOverride_fuzzyArrows() {
1892 m(B a) {} 2827 checkFile('''
1893 } 2828 abstract class A {
1894 2829 bool operator ==(Object object);
1895 class T1 extends Base with /*severe:InvalidMethodOverride*/M { 2830 }
1896 } 2831
1897 ''' 2832 class B implements A {}
1898 }); 2833
1899 testChecker('interface of concrete superclass', { 2834 class F {
1900 '/main.dart': ''' 2835 void f(x) {}
1901 class A {} 2836 void g(int x) {}
1902 class B {} 2837 }
1903 2838
1904 abstract class I1 { 2839 class G extends F {
1905 m(A a); 2840 /*error:INVALID_METHOD_OVERRIDE*/void f(int x) {}
1906 } 2841 void g(dynamic x) {}
1907 2842 }
1908 // See issue #25 2843
1909 /*pass should be warning:AnalyzerError*/class Base implements I1 { 2844 class H implements F {
1910 } 2845 /*error:INVALID_METHOD_OVERRIDE*/void f(int x) {}
1911 2846 void g(dynamic x) {}
1912 class M { 2847 }
1913 m(B a) {} 2848 ''');
1914 } 2849 }
1915 2850
1916 class T1 extends Base with M { 2851 void test_methodTearoffStrictArrow() {
1917 } 2852 // Regression test for https://github.com/dart-lang/sdk/issues/26393
1918 ''' 2853 checkFile(r'''
1919 }); 2854 class A {
1920 }); 2855 void foo(dynamic x) {}
1921 2856 void test(void f(int x)) {
1922 group('superclass override of grand interface', () { 2857 test(foo);
1923 testChecker('interface of interface of child', { 2858 }
1924 '/main.dart': ''' 2859 }
1925 class A {} 2860 ''');
1926 class B {} 2861 }
1927 2862
1928 abstract class I1 { 2863 void test_mixinOverrideOfGrandInterface_interfaceOfAbstractSuperclass() {
1929 m(A a); 2864 checkFile('''
1930 } 2865 class A {}
1931 abstract class I2 implements I1 {} 2866 class B {}
1932 2867
1933 class Base { 2868 abstract class I1 {
1934 m(B a) {} 2869 m(A a);
1935 } 2870 }
1936 2871 abstract class Base implements I1 {}
1937 class T1 /*severe:InvalidMethodOverride*/extends Base 2872
1938 implements I2 { 2873 class M {
1939 } 2874 m(B a) {}
1940 ''' 2875 }
1941 }); 2876
1942 testChecker('superclass of interface of child', { 2877 class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
1943 '/main.dart': ''' 2878 with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M {}
1944 class A {} 2879 ''');
1945 class B {} 2880 }
1946 2881
1947 abstract class I1 { 2882 void test_mixinOverrideOfGrandInterface_interfaceOfConcreteSuperclass() {
1948 m(A a); 2883 checkFile('''
1949 } 2884 class A {}
1950 abstract class I2 extends I1 {} 2885 class B {}
1951 2886
1952 class Base { 2887 abstract class I1 {
1953 m(B a) {} 2888 m(A a);
1954 } 2889 }
1955 2890
1956 class T1 /*severe:InvalidMethodOverride*/extends Base 2891 class /*error:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/Base
1957 implements I2 { 2892 implements I1 {}
1958 } 2893
1959 ''' 2894 class M {
1960 }); 2895 m(B a) {}
1961 testChecker('mixin of interface of child', { 2896 }
1962 '/main.dart': ''' 2897
1963 class A {} 2898 class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
1964 class B {} 2899 with M {}
1965 2900 ''');
1966 abstract class M1 { 2901 }
1967 m(A a); 2902
1968 } 2903 void test_mixinOverrideOfGrandInterface_interfaceOfInterfaceOfChild() {
1969 abstract class I2 extends Object with M1 {} 2904 checkFile('''
1970 2905 class A {}
1971 class Base { 2906 class B {}
1972 m(B a) {} 2907
1973 } 2908 abstract class I1 {
1974 2909 m(A a);
1975 class T1 /*severe:InvalidMethodOverride*/extends Base 2910 }
1976 implements I2 { 2911 abstract class I2 implements I1 {}
1977 } 2912
1978 ''' 2913 class M {
1979 }); 2914 m(B a) {}
1980 testChecker('interface of abstract superclass', { 2915 }
1981 '/main.dart': ''' 2916
1982 class A {} 2917 class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1
1983 class B {} 2918 extends Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M
1984 2919 implements I2 {}
1985 abstract class I1 { 2920 ''');
1986 m(A a); 2921 }
1987 } 2922
1988 2923 void test_mixinOverrideOfGrandInterface_mixinOfInterfaceOfChild() {
1989 abstract class Base implements I1 { 2924 checkFile('''
1990 /*severe:InvalidMethodOverride*/m(B a) {} 2925 class A {}
1991 } 2926 class B {}
1992 2927
1993 class T1 extends Base { 2928 abstract class M1 {
1994 // we consider the base class incomplete because it is 2929 m(A a);
1995 // abstract, so we report the error here too. 2930 }
1996 // TODO(sigmund): consider tracking overrides in a fine-grain 2931 abstract class I2 extends Object with M1 {}
1997 // manner, then this and the double-overrides would not be 2932
1998 // reported. 2933 class M {
1999 /*severe:InvalidMethodOverride*/m(B a) {} 2934 m(B a) {}
2000 } 2935 }
2001 ''' 2936
2002 }); 2937 class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1
2003 testChecker('interface of concrete superclass', { 2938 extends Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M
2004 '/main.dart': ''' 2939 implements I2 {}
2005 class A {} 2940 ''');
2006 class B {} 2941 }
2007 2942
2008 abstract class I1 { 2943 void test_mixinOverrideOfGrandInterface_superclassOfInterfaceOfChild() {
2009 m(A a); 2944 checkFile('''
2010 } 2945 class A {}
2011 2946 class B {}
2012 class Base implements I1 { 2947
2013 /*severe:InvalidMethodOverride*/m(B a) {} 2948 abstract class I1 {
2014 } 2949 m(A a);
2015 2950 }
2016 class T1 extends Base { 2951 abstract class I2 extends I1 {}
2017 m(B a) {} 2952
2018 } 2953 class M {
2019 ''' 2954 m(B a) {}
2020 }); 2955 }
2021 }); 2956
2022 2957 class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1
2023 group('no duplicate reports from overriding interfaces', () { 2958 extends Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M
2024 testChecker('type overrides same method in multiple interfaces', { 2959 implements I2 {}
2025 '/main.dart': ''' 2960 ''');
2026 class A {} 2961 }
2027 class B {} 2962
2028 2963 void
2029 abstract class I1 { 2964 test_noDuplicateReportsFromOverridingInterfaces_baseTypeAndMixinOverrideSa meMethodInInterface() {
2030 m(A a); 2965 checkFile('''
2031 } 2966 class A {}
2032 abstract class I2 implements I1 { 2967 class B {}
2033 m(A a); 2968
2034 } 2969 abstract class I1 {
2035 2970 m(A a);
2036 class Base { 2971 }
2037 } 2972
2038 2973 class Base {
2039 class T1 implements I2 { 2974 m(B a) {}
2040 /*severe:InvalidMethodOverride*/m(B a) {} 2975 }
2041 } 2976
2042 ''' 2977 class M {
2043 }); 2978 m(B a) {}
2044 2979 }
2045 testChecker('type and base type override same method in interface', { 2980
2046 '/main.dart': ''' 2981 // Here we want to report both, because the error location is
2047 class A {} 2982 // different.
2048 class B {} 2983 // TODO(sigmund): should we merge these as well?
2049 2984 class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1
2050 abstract class I1 { 2985 /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base
2051 m(A a); 2986 with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M
2052 } 2987 implements I1 {}
2053 2988 ''');
2054 class Base { 2989 }
2055 m(B a); 2990
2056 } 2991 void
2057 2992 test_noDuplicateReportsFromOverridingInterfaces_twoGrandTypesOverrideSameM ethodInInterface() {
2058 // Note: no error reported in `extends Base` to avoid duplicating 2993 checkFile('''
2059 // the error in T1. 2994 class A {}
2060 class T1 extends Base implements I1 { 2995 class B {}
2061 /*severe:InvalidMethodOverride*/m(B a) {} 2996
2062 } 2997 abstract class I1 {
2063 2998 m(A a);
2064 // If there is no error in the class, we do report the error at 2999 }
2065 // the base class: 3000
2066 class T2 /*severe:InvalidMethodOverride*/extends Base 3001 class Grandparent {
2067 implements I1 { 3002 m(B a) {}
2068 } 3003 }
2069 ''' 3004
2070 }); 3005 class Parent1 extends Grandparent {
2071 3006 m(B a) {}
2072 testChecker('type and mixin override same method in interface', { 3007 }
2073 '/main.dart': ''' 3008 class Parent2 extends Grandparent {}
2074 class A {} 3009
2075 class B {} 3010 // Note: otherwise both errors would be reported on this line
2076 3011 class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1
2077 abstract class I1 { 3012 /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Parent1
2078 m(A a); 3013 implements I1 {}
2079 } 3014 class /*error:INCONSISTENT_METHOD_INHERITANCE*/T2
2080 3015 /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Parent2
2081 class M { 3016 implements I1 {}
2082 m(B a); 3017 ''');
2083 } 3018 }
2084 3019
2085 class T1 extends Object with M implements I1 { 3020 void
2086 /*severe:InvalidMethodOverride*/m(B a) {} 3021 test_noDuplicateReportsFromOverridingInterfaces_twoMixinsOverrideSameMetho dInInterface() {
2087 } 3022 checkFile('''
2088 3023 class A {}
2089 class T2 extends Object with /*severe:InvalidMethodOverride*/M 3024 class B {}
2090 implements I1 { 3025
2091 } 3026 abstract class I1 {
2092 ''' 3027 m(A a);
2093 }); 3028 }
2094 3029
2095 testChecker('two grand types override same method in interface', { 3030 class M1 {
2096 '/main.dart': ''' 3031 m(B a) {}
2097 class A {} 3032 }
2098 class B {} 3033
2099 3034 class M2 {
2100 abstract class I1 { 3035 m(B a) {}
2101 m(A a); 3036 }
2102 } 3037
2103 3038 // Here we want to report both, because the error location is
2104 class Grandparent { 3039 // different.
2105 m(B a) {} 3040 // TODO(sigmund): should we merge these as well?
2106 } 3041 class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Object
2107 3042 with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M1,
2108 class Parent1 extends Grandparent { 3043 /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M2
2109 m(B a) {} 3044 implements I1 {}
2110 } 3045 ''');
2111 class Parent2 extends Grandparent { 3046 }
2112 } 3047
2113 3048 void
2114 // Note: otherwise both errors would be reported on this line 3049 test_noDuplicateReportsFromOverridingInterfaces_typeAndBaseTypeOverrideSam eMethodInInterface() {
2115 class T1 /*severe:InvalidMethodOverride*/extends Parent1 3050 checkFile('''
2116 implements I1 { 3051 class A {}
2117 } 3052 class B {}
2118 class T2 /*severe:InvalidMethodOverride*/extends Parent2 3053
2119 implements I1 { 3054 abstract class I1 {
2120 } 3055 m(A a);
2121 ''' 3056 }
2122 }); 3057
2123 3058 class Base {
2124 testChecker('two mixins override same method in interface', { 3059 m(B a) {}
2125 '/main.dart': ''' 3060 }
2126 class A {} 3061
2127 class B {} 3062 // Note: no error reported in `extends Base` to avoid duplicating
2128 3063 // the error in T1.
2129 abstract class I1 { 3064 class T1 extends Base implements I1 {
2130 m(A a); 3065 /*error:INVALID_METHOD_OVERRIDE*/m(B a) {}
2131 } 3066 }
2132 3067
2133 class M1 { 3068 // If there is no error in the class, we do report the error at
2134 m(B a) {} 3069 // the base class:
2135 } 3070 class /*error:INCONSISTENT_METHOD_INHERITANCE*/T2
2136 3071 /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base
2137 class M2 { 3072 implements I1 {}
2138 m(B a) {} 3073 ''');
2139 } 3074 }
2140 3075
2141 // Here we want to report both, because the error location is 3076 void
2142 // different. 3077 test_noDuplicateReportsFromOverridingInterfaces_typeAndMixinOverrideSameMe thodInInterface() {
2143 // TODO(sigmund): should we merge these as well? 3078 checkFile('''
2144 class T1 extends Object 3079 class A {}
2145 with /*severe:InvalidMethodOverride*/M1 3080 class B {}
2146 with /*severe:InvalidMethodOverride*/M2 3081
2147 implements I1 { 3082 abstract class I1 {
2148 } 3083 m(A a);
2149 ''' 3084 }
2150 }); 3085
2151 3086 class M {
2152 testChecker('base type and mixin override same method in interface', { 3087 m(B a) {}
2153 '/main.dart': ''' 3088 }
2154 class A {} 3089
2155 class B {} 3090 class T1 extends Object with M implements I1 {
2156 3091 /*error:INVALID_METHOD_OVERRIDE*/m(B a) {}
2157 abstract class I1 { 3092 }
2158 m(A a); 3093
2159 } 3094 class /*error:INCONSISTENT_METHOD_INHERITANCE*/T2
2160 3095 extends Object with /*error:INVALID_METHOD_OVERRIDE_FROM_MIXIN*/M
2161 class Base { 3096 implements I1 {}
2162 m(B a) {} 3097 ''');
2163 } 3098 }
2164 3099
2165 class M { 3100 void
2166 m(B a) {} 3101 test_noDuplicateReportsFromOverridingInterfaces_typeOverridesSomeMethodInM ultipleInterfaces() {
2167 } 3102 checkFile('''
2168 3103 class A {}
2169 // Here we want to report both, because the error location is 3104 class B {}
2170 // different. 3105
2171 // TODO(sigmund): should we merge these as well? 3106 abstract class I1 {
2172 class T1 /*severe:InvalidMethodOverride*/extends Base 3107 m(A a);
2173 with /*severe:InvalidMethodOverride*/M 3108 }
2174 implements I1 { 3109 abstract class I2 implements I1 {
2175 } 3110 m(A a);
2176 ''' 3111 }
2177 }); 3112
2178 }); 3113 class Base {}
2179 3114
2180 testChecker('invalid runtime checks', { 3115 class T1 implements I2 {
2181 '/main.dart': ''' 3116 /*error:INVALID_METHOD_OVERRIDE*/m(B a) {}
2182 typedef int I2I(int x); 3117 }
2183 typedef int D2I(x); 3118 ''');
2184 typedef int II2I(int x, int y); 3119 }
2185 typedef int DI2I(x, int y); 3120
2186 typedef int ID2I(int x, y); 3121 void test_nullCoalescingOperator() {
2187 typedef int DD2I(x, y); 3122 checkFile('''
2188 3123 class A {}
2189 typedef I2D(int x); 3124 class C<T> {}
2190 typedef D2D(x); 3125 main() {
2191 typedef II2D(int x, int y); 3126 A a, b;
2192 typedef DI2D(x, int y); 3127 a ??= new A();
2193 typedef ID2D(int x, y); 3128 b = b ?? new A();
2194 typedef DD2D(x, y); 3129
2195 3130 // downwards inference
2196 int foo(int x) => x; 3131 C<int> c, d;
2197 int bar(int x, int y) => x + y; 3132 c ??= /*info:INFERRED_TYPE_ALLOCATION*/new C();
2198 3133 d = d ?? /*info:INFERRED_TYPE_ALLOCATION*/new C();
2199 void main() { 3134 }
2200 bool b; 3135 ''');
2201 b = /*info:NonGroundTypeCheckInfo*/foo is I2I; 3136 }
2202 b = /*info:NonGroundTypeCheckInfo*/foo is D2I; 3137
2203 b = /*info:NonGroundTypeCheckInfo*/foo is I2D; 3138 void test_nullCoalescingStrictArrow() {
2204 b = foo is D2D; 3139 checkFile(r'''
2205 3140 bool _alwaysTrue(x) => true;
2206 b = /*info:NonGroundTypeCheckInfo*/bar is II2I; 3141 typedef bool TakesA<T>(T t);
2207 b = /*info:NonGroundTypeCheckInfo*/bar is DI2I; 3142 class C<T> {
2208 b = /*info:NonGroundTypeCheckInfo*/bar is ID2I; 3143 TakesA<T> g;
2209 b = /*info:NonGroundTypeCheckInfo*/bar is II2D; 3144 C(TakesA<T> f)
2210 b = /*info:NonGroundTypeCheckInfo*/bar is DD2I; 3145 : g = f ?? _alwaysTrue;
2211 b = /*info:NonGroundTypeCheckInfo*/bar is DI2D; 3146 C.a() : g = _alwaysTrue;
2212 b = /*info:NonGroundTypeCheckInfo*/bar is ID2D; 3147 }
2213 b = bar is DD2D; 3148 ''');
2214 3149 }
2215 // For as, the validity of checks is deferred to runtime. 3150
2216 Function f; 3151 void test_optionalParams() {
2217 f = foo as I2I; 3152 // Regression test for https://github.com/dart-lang/sdk/issues/26155
2218 f = foo as D2I; 3153 checkFile(r'''
2219 f = foo as I2D; 3154 void takesF(void f(int x)) {
2220 f = foo as D2D; 3155 takesF(/*info:INFERRED_TYPE_CLOSURE,info:INFERRED_TYPE_CLOSURE*/([x]) { bool z = x.isEven; });
2221 3156 takesF(/*info:INFERRED_TYPE_CLOSURE*/(y) { bool z = y.isEven; });
2222 f = bar as II2I; 3157 }
2223 f = bar as DI2I; 3158 ''');
2224 f = bar as ID2I; 3159 }
2225 f = bar as II2D; 3160
2226 f = bar as DD2I; 3161 void test_overrideNarrowsType() {
2227 f = bar as DI2D; 3162 addFile(r'''
2228 f = bar as ID2D; 3163 class A {}
2229 f = bar as DD2D; 3164 class B extends A {}
2230 } 3165
2231 ''' 3166 abstract class C {
2232 }); 3167 m(A a);
2233 3168 n(B b);
2234 group('function modifiers', () { 3169 }
2235 testChecker('async', { 3170 abstract class D extends C {
2236 '/main.dart': ''' 3171 /*error:INVALID_METHOD_OVERRIDE*/m(B b);
2237 import 'dart:async'; 3172 n(A a);
2238 import 'dart:math' show Random; 3173 }
2239 3174 ''');
2240 dynamic x; 3175 check(implicitCasts: false);
2241 3176 }
2242 foo1() async => x; 3177
2243 Future foo2() async => x; 3178 void test_overrideNarrowsType_noDuplicateError() {
2244 Future<int> foo3() async => (/*info:DynamicCast*/x); 3179 // Regression test for https://github.com/dart-lang/sdk/issues/25232
2245 Future<int> foo4() async => (/*severe:StaticTypeError*/new Future<int>.v alue(/*info:DynamicCast*/x)); 3180 _addMetaLibrary();
2246 3181 checkFile(r'''
2247 bar1() async { return x; } 3182 import 'meta.dart';
2248 Future bar2() async { return x; } 3183 abstract class A { void test(A arg) { } }
2249 Future<int> bar3() async { return (/*info:DynamicCast*/x); } 3184 abstract class B extends A {
2250 Future<int> bar4() async { return (/*severe:StaticTypeError*/new Future< int>.value(/*info:DynamicCast*/x)); } 3185 /*error:INVALID_METHOD_OVERRIDE*/void test(B arg) { }
2251 3186 }
2252 int y; 3187 abstract class X implements A { }
2253 Future<int> z; 3188 class C extends B with X { }
2254 3189
2255 void baz() async { 3190 // We treat "implements A" as asking for another check.
2256 int a = /*info:DynamicCast*/await x; 3191 // This feels inconsistent to me.
2257 int b = await y; 3192 class D /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends B implements A { }
2258 int c = await z; 3193 ''');
2259 String d = /*severe:StaticTypeError*/await z; 3194 }
2260 } 3195
2261 3196 void test_overrideNarrowsType_legalWithChecked() {
2262 Future<bool> get issue_264 async { 3197 // Regression test for https://github.com/dart-lang/sdk/issues/25232
2263 await 42; 3198 _addMetaLibrary();
2264 if (new Random().nextBool()) { 3199 checkFile(r'''
2265 return true; 3200 import 'meta.dart';
2266 } else { 3201 abstract class A { void test(A arg) { } }
2267 return /*severe:StaticTypeError*/new Future<bool>.value(false); 3202 abstract class B extends A { void test(@checked B arg) { } }
2268 } 3203 abstract class X implements A { }
2269 } 3204 class C extends B with X { }
2270 ''' 3205 class D extends B implements A { }
2271 }); 3206 ''');
2272 3207 }
2273 testChecker('async*', { 3208
2274 '/main.dart': ''' 3209 void test_privateOverride() {
2275 import 'dart:async'; 3210 addFile(
2276 3211 '''
2277 dynamic x; 3212 import 'main.dart' as main;
2278 3213
2279 bar1() async* { yield x; } 3214 class Base {
2280 Stream bar2() async* { yield x; } 3215 var f1;
2281 Stream<int> bar3() async* { yield (/*info:DynamicCast*/x); } 3216 var _f2;
2282 Stream<int> bar4() async* { yield (/*severe:StaticTypeError*/new Stream< int>()); } 3217 var _f3;
2283 3218 get _f4 => null;
2284 baz1() async* { yield* (/*info:DynamicCast*/x); } 3219
2285 Stream baz2() async* { yield* (/*info:DynamicCast*/x); } 3220 int _m1() => null;
2286 Stream<int> baz3() async* { yield* (/*warning:DownCastComposite*/x); } 3221 }
2287 Stream<int> baz4() async* { yield* new Stream<int>(); } 3222
2288 Stream<int> baz5() async* { yield* (/*info:InferredTypeAllocation*/new S tream()); } 3223 class GrandChild extends main.Child {
2289 ''' 3224 /*error:INVALID_FIELD_OVERRIDE*/var _f2;
2290 }); 3225 /*error:INVALID_FIELD_OVERRIDE*/var _f3;
2291 3226 var _f4;
2292 testChecker('sync*', { 3227
2293 '/main.dart': ''' 3228 /*error:INVALID_METHOD_OVERRIDE*/String _m1() => null;
2294 import 'dart:async'; 3229 }
2295 3230 ''',
2296 dynamic x; 3231 name: '/helper.dart');
2297 3232 checkFile('''
2298 bar1() sync* { yield x; } 3233 import 'helper.dart' as helper;
2299 Iterable bar2() sync* { yield x; } 3234
2300 Iterable<int> bar3() sync* { yield (/*info:DynamicCast*/x); } 3235 class Child extends helper.Base {
2301 Iterable<int> bar4() sync* { yield (/*severe:StaticTypeError*/new Iterab le<int>()); } 3236 /*error:INVALID_FIELD_OVERRIDE*/var f1;
2302 3237 var _f2;
2303 baz1() sync* { yield* (/*info:DynamicCast*/x); } 3238 var _f4;
2304 Iterable baz2() sync* { yield* (/*info:DynamicCast*/x); } 3239
2305 Iterable<int> baz3() sync* { yield* (/*warning:DownCastComposite*/x); } 3240 String _m1() => null;
2306 Iterable<int> baz4() sync* { yield* new Iterable<int>(); } 3241 }
2307 Iterable<int> baz5() sync* { yield* (/*info:InferredTypeAllocation*/new Iterable()); } 3242 ''');
2308 ''' 3243 }
2309 }); 3244
2310 }); 3245 void test_proxy() {
2311 } 3246 checkFile(r'''
3247 @proxy class C {}
3248 @proxy class D {
3249 var f;
3250 m() => null;
3251 operator -() => null;
3252 operator +(int other) => null;
3253 operator [](int index) => null;
3254 call() => null;
3255 }
3256 @proxy class F implements Function { noSuchMethod(i) => 42; }
3257
3258
3259 m() {
3260 D d = new D();
3261 d.m();
3262 d.m;
3263 d.f;
3264 -d;
3265 d + 7;
3266 d[7];
3267 d();
3268
3269 C c = new C();
3270 /*info:DYNAMIC_INVOKE*/c.m();
3271 /*info:DYNAMIC_INVOKE*/c.m;
3272 /*info:DYNAMIC_INVOKE*/-c;
3273 /*info:DYNAMIC_INVOKE*/c + 7;
3274 /*info:DYNAMIC_INVOKE*/c[7];
3275 /*error:INVOCATION_OF_NON_FUNCTION,info:DYNAMIC_INVOKE*/c();
3276
3277 F f = new F();
3278 /*info:DYNAMIC_INVOKE*/f();
3279 }
3280 ''');
3281 }
3282
3283 void test_redirectingConstructor() {
3284 checkFile('''
3285 class A {
3286 A(A x) {}
3287 A.two() : this(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
3288 }
3289 ''');
3290 }
3291
3292 void test_relaxedCasts() {
3293 checkFile('''
3294 class A {}
3295
3296 class L<T> {}
3297 class M<T> extends L<T> {}
3298 // L<dynamic|Object>
3299 // / \
3300 // M<dynamic|Object> L<A>
3301 // \ /
3302 // M<A>
3303 // In normal Dart, there are additional edges
3304 // from M<A> to M<dynamic>
3305 // from L<A> to M<dynamic>
3306 // from L<A> to L<dynamic>
3307 void main() {
3308 L lOfDs;
3309 L<Object> lOfOs;
3310 L<A> lOfAs;
3311
3312 M mOfDs;
3313 M<Object> mOfOs;
3314 M<A> mOfAs;
3315
3316 {
3317 lOfDs = mOfDs;
3318 lOfDs = mOfOs;
3319 lOfDs = mOfAs;
3320 lOfDs = lOfDs;
3321 lOfDs = lOfOs;
3322 lOfDs = lOfAs;
3323 lOfDs = new L(); // Reset type propagation.
3324 }
3325 {
3326 lOfOs = mOfDs;
3327 lOfOs = mOfOs;
3328 lOfOs = mOfAs;
3329 lOfOs = lOfDs;
3330 lOfOs = lOfOs;
3331 lOfOs = lOfAs;
3332 lOfOs = new L<Object>(); // Reset type propagation.
3333 }
3334 {
3335 lOfAs = /*error:INVALID_ASSIGNMENT*/mOfDs;
3336 lOfAs = /*error:INVALID_ASSIGNMENT*/mOfOs;
3337 lOfAs = mOfAs;
3338 lOfAs = /*warning:DOWN_CAST_COMPOSITE*/lOfDs;
3339 lOfAs = /*info:DOWN_CAST_IMPLICIT*/lOfOs;
3340 lOfAs = lOfAs;
3341 lOfAs = new L<A>(); // Reset type propagation.
3342 }
3343 {
3344 mOfDs = mOfDs;
3345 mOfDs = mOfOs;
3346 mOfDs = mOfAs;
3347 mOfDs = /*info:DOWN_CAST_IMPLICIT*/lOfDs;
3348 mOfDs = /*info:DOWN_CAST_IMPLICIT*/lOfOs;
3349 mOfDs = /*error:INVALID_ASSIGNMENT*/lOfAs;
3350 mOfDs = new M(); // Reset type propagation.
3351 }
3352 {
3353 mOfOs = mOfDs;
3354 mOfOs = mOfOs;
3355 mOfOs = mOfAs;
3356 mOfOs = /*info:DOWN_CAST_IMPLICIT*/lOfDs;
3357 mOfOs = /*info:DOWN_CAST_IMPLICIT*/lOfOs;
3358 mOfOs = /*error:INVALID_ASSIGNMENT*/lOfAs;
3359 mOfOs = new M<Object>(); // Reset type propagation.
3360 }
3361 {
3362 mOfAs = /*warning:DOWN_CAST_COMPOSITE*/mOfDs;
3363 mOfAs = /*info:DOWN_CAST_IMPLICIT*/mOfOs;
3364 mOfAs = mOfAs;
3365 mOfAs = /*warning:DOWN_CAST_COMPOSITE*/lOfDs;
3366 mOfAs = /*info:DOWN_CAST_IMPLICIT*/lOfOs;
3367 mOfAs = /*info:DOWN_CAST_IMPLICIT*/lOfAs;
3368 }
3369 }
3370 ''');
3371 }
3372
3373 void test_setterOverride_fuzzyArrows() {
3374 checkFile('''
3375 typedef void ToVoid<T>(T x);
3376 class F {
3377 void set f(ToVoid<dynamic> x) {}
3378 void set g(ToVoid<int> x) {}
3379 void set h(dynamic x) {}
3380 void set i(int x) {}
3381 }
3382
3383 class G extends F {
3384 /*error:INVALID_METHOD_OVERRIDE*/void set f(ToVoid<int> x) {}
3385 void set g(ToVoid<dynamic> x) {}
3386 /*error:INVALID_METHOD_OVERRIDE*/void set h(int x) {}
3387 void set i(dynamic x) {}
3388 }
3389
3390 class H implements F {
3391 /*error:INVALID_METHOD_OVERRIDE*/void set f(ToVoid<int> x) {}
3392 void set g(ToVoid<dynamic> x) {}
3393 /*error:INVALID_METHOD_OVERRIDE*/void set h(int x) {}
3394 void set i(dynamic x) {}
3395 }
3396 ''');
3397 }
3398
3399 void test_setterReturnTypes() {
3400 checkFile('''
3401 void voidFn() => null;
3402 class A {
3403 set a(y) => 4;
3404 set b(y) => voidFn();
3405 void set c(y) => /*error:RETURN_OF_INVALID_TYPE*/4;
3406 void set d(y) => voidFn();
3407 /*warning:NON_VOID_RETURN_FOR_SETTER*/int set e(y) => 4;
3408 /*warning:NON_VOID_RETURN_FOR_SETTER*/int set f(y) =>
3409 /*error:RETURN_OF_INVALID_TYPE*/voidFn();
3410 set g(y) {return /*error:RETURN_OF_INVALID_TYPE*/4;}
3411 void set h(y) {return /*error:RETURN_OF_INVALID_TYPE*/4;}
3412 /*warning:NON_VOID_RETURN_FOR_SETTER*/int set i(y) {return 4;}
3413 }
3414 ''');
3415 }
3416
3417 void test_setterSetterOverride() {
3418 checkFile('''
3419 class A {}
3420 class B extends A {}
3421 class C extends B {}
3422
3423 abstract class Base {
3424 void set f1(B value);
3425 void set f2(B value);
3426 void set f3(B value);
3427 void set f4(B value);
3428 void set f5(B value);
3429 }
3430
3431 class Child extends Base {
3432 void set f1(A value) {}
3433 /*error:INVALID_METHOD_OVERRIDE*/void set f2(C value) {}
3434 void set f3(value) {}
3435 void set f4(dynamic value) {}
3436 set f5(B value) {}
3437 }
3438 ''');
3439 }
3440
3441 void test_superCallPlacement() {
3442 checkFile('''
3443 class Base {
3444 var x;
3445 Base() : x = print('Base.1') { print('Base.2'); }
3446 }
3447
3448 class Derived extends Base {
3449 var y, z;
3450 Derived()
3451 : y = print('Derived.1'),
3452 /*error:INVALID_SUPER_INVOCATION*/super(),
3453 z = print('Derived.2') {
3454 print('Derived.3');
3455 }
3456 }
3457
3458 class Valid extends Base {
3459 var y, z;
3460 Valid()
3461 : y = print('Valid.1'),
3462 z = print('Valid.2'),
3463 super() {
3464 print('Valid.3');
3465 }
3466 }
3467
3468 class AlsoValid extends Base {
3469 AlsoValid() : super();
3470 }
3471
3472 main() => new Derived();
3473 ''');
3474 }
3475
3476 void test_superclassOverrideOfGrandInterface_interfaceOfAbstractSuperclass() {
3477 checkFile('''
3478 class A {}
3479 class B {}
3480
3481 abstract class I1 {
3482 m(A a);
3483 }
3484
3485 abstract class Base implements I1 {
3486 /*error:INVALID_METHOD_OVERRIDE*/m(B a) {}
3487 }
3488
3489 class T1 extends Base {
3490 // we consider the base class incomplete because it is
3491 // abstract, so we report the error here too.
3492 // TODO(sigmund): consider tracking overrides in a fine-grain
3493 // manner, then this and the double-overrides would not be
3494 // reported.
3495 /*error:INVALID_METHOD_OVERRIDE*/m(B a) {}
3496 }
3497 ''');
3498 }
3499
3500 void test_superclassOverrideOfGrandInterface_interfaceOfConcreteSuperclass() {
3501 checkFile('''
3502 class A {}
3503 class B {}
3504
3505 abstract class I1 {
3506 m(A a);
3507 }
3508
3509 class Base implements I1 {
3510 /*error:INVALID_METHOD_OVERRIDE*/m(B a) {}
3511 }
3512
3513 class T1 extends Base {
3514 m(B a) {}
3515 }
3516 ''');
3517 }
3518
3519 void test_superclassOverrideOfGrandInterface_interfaceOfInterfaceOfChild() {
3520 checkFile('''
3521 class A {}
3522 class B {}
3523
3524 abstract class I1 {
3525 m(A a);
3526 }
3527 abstract class I2 implements I1 {}
3528
3529 class Base {
3530 m(B a) {}
3531 }
3532
3533 class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1
3534 /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base implements I2 {}
3535 ''');
3536 }
3537
3538 void test_superclassOverrideOfGrandInterface_mixinOfInterfaceOfChild() {
3539 checkFile('''
3540 class A {}
3541 class B {}
3542
3543 abstract class M1 {
3544 m(A a);
3545 }
3546 abstract class I2 extends Object with M1 {}
3547
3548 class Base {
3549 m(B a) {}
3550 }
3551
3552 class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1
3553 /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base
3554 implements I2 {}
3555 ''');
3556 }
3557
3558 void test_superclassOverrideOfGrandInterface_superclassOfInterfaceOfChild() {
3559 checkFile('''
3560 class A {}
3561 class B {}
3562
3563 abstract class I1 {
3564 m(A a);
3565 }
3566 abstract class I2 extends I1 {}
3567
3568 class Base {
3569 m(B a) {}
3570 }
3571
3572 class /*error:INCONSISTENT_METHOD_INHERITANCE*/T1
3573 /*error:INVALID_METHOD_OVERRIDE_FROM_BASE*/extends Base
3574 implements I2 {}
3575 ''');
3576 }
3577
3578 void test_superConstructor() {
3579 checkFile('''
3580 class A { A(A x) {} }
3581 class B extends A {
3582 B() : super(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
3583 }
3584 ''');
3585 }
3586
3587 void test_ternaryOperator() {
3588 checkFile('''
3589 abstract class Comparable<T> {
3590 int compareTo(T other);
3591 static int compare(Comparable a, Comparable b) => a.compareTo(b);
3592 }
3593 typedef int Comparator<T>(T a, T b);
3594
3595 typedef bool _Predicate<T>(T value);
3596
3597 class SplayTreeMap<K, V> {
3598 Comparator<K> _comparator;
3599 _Predicate _validKey;
3600
3601 // The warning on assigning to _comparator is legitimate. Since K has
3602 // no bound, all we know is that it's object. _comparator's function
3603 // type is effectively: (Object, Object) -> int
3604 // We are assigning it a fn of type: (Comparable, Comparable) -> int
3605 // There's no telling if that will work. For example, consider:
3606 //
3607 // new SplayTreeMap<Uri>();
3608 //
3609 // This would end up calling .compareTo() on a Uri, which doesn't
3610 // define that since it doesn't implement Comparable.
3611 SplayTreeMap([int compare(K key1, K key2),
3612 bool isValidKey(potentialKey)])
3613 : _comparator = /*warning:DOWN_CAST_COMPOSITE*/(compare == null) ? Comparabl e.compare : compare,
3614 _validKey = (isValidKey != null) ? isValidKey : ((v) => true) {
3615
3616 // NOTE: this is a down cast because isValidKey has fuzzy arrow type.
3617 _Predicate<Object> v = /*warning:DOWN_CAST_COMPOSITE*/(isValidKey != null)
3618 ? isValidKey : (/*info:INFERRED_TYPE_CLOSURE*/(_) => true);
3619
3620 v = (isValidKey != null)
3621 ? v : (/*info:INFERRED_TYPE_CLOSURE*/(_) => true);
3622 }
3623 }
3624 void main() {
3625 Object obj = 42;
3626 dynamic dyn = 42;
3627 int i = 42;
3628
3629 // Check the boolean conversion of the condition.
3630 print(/*error:NON_BOOL_CONDITION*/i ? false : true);
3631 print((/*info:DOWN_CAST_IMPLICIT*/obj) ? false : true);
3632 print((/*info:DYNAMIC_CAST*/dyn) ? false : true);
3633 }
3634 ''');
3635 }
3636
3637 void test_typeCheckingLiterals() {
3638 checkFile('''
3639 test() {
3640 num n = 3;
3641 int i = 3;
3642 String s = "hello";
3643 {
3644 List<int> l = <int>[i];
3645 l = <int>[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/s];
3646 l = <int>[/*info:DOWN_CAST_IMPLICIT*/n];
3647 l = <int>[i, /*info:DOWN_CAST_IMPLICIT*/n, /*error:LIST_ELEMENT_TYPE_NOT_AS SIGNABLE*/s];
3648 }
3649 {
3650 List l = /*info:INFERRED_TYPE_LITERAL*/[i];
3651 l = /*info:INFERRED_TYPE_LITERAL*/[s];
3652 l = /*info:INFERRED_TYPE_LITERAL*/[n];
3653 l = /*info:INFERRED_TYPE_LITERAL*/[i, n, s];
3654 }
3655 {
3656 Map<String, int> m = <String, int>{s: i};
3657 m = <String, int>{s: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/s};
3658 m = <String, int>{s: /*info:DOWN_CAST_IMPLICIT*/n};
3659 m = <String, int>{s: i,
3660 s: /*info:DOWN_CAST_IMPLICIT*/n,
3661 s: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/s};
3662 }
3663 // TODO(leafp): We can't currently test for key errors since the
3664 // error marker binds to the entire entry.
3665 {
3666 Map m = /*info:INFERRED_TYPE_LITERAL*/{s: i};
3667 m = /*info:INFERRED_TYPE_LITERAL*/{s: s};
3668 m = /*info:INFERRED_TYPE_LITERAL*/{s: n};
3669 m = /*info:INFERRED_TYPE_LITERAL*/
3670 {s: i,
3671 s: n,
3672 s: s};
3673 m = /*info:INFERRED_TYPE_LITERAL*/
3674 {i: s,
3675 n: s,
3676 s: s};
3677 }
3678 }
3679 ''');
3680 }
3681
3682 void test_typePromotionFromDynamic() {
3683 checkFile(r'''
3684 f() {
3685 dynamic x;
3686 if (x is int) {
3687 int y = x;
3688 String z = /*error:INVALID_ASSIGNMENT*/x;
3689 }
3690 }
3691 g() {
3692 Object x;
3693 if (x is int) {
3694 int y = x;
3695 String z = /*error:INVALID_ASSIGNMENT*/x;
3696 }
3697 }
3698 ''');
3699 }
3700
3701 void test_typePromotionFromTypeParameter() {
3702 // Regression test for https://github.com/dart-lang/sdk/issues/26965
3703 checkFile(r'''
3704 void f/*<T>*/(/*=T*/ object) {
3705 if (object is String) print(object.substring(1));
3706 }
3707 void g/*<T extends num>*/(/*=T*/ object) {
3708 if (object is int) print(object.isEven);
3709 if (object is String) print(/*info:DYNAMIC_INVOKE*/object.substring(1));
3710 }
3711 class Clonable<T> {}
3712 class SubClonable<T> extends Clonable<T> {
3713 T m(T t) => t;
3714 }
3715 void h/*<T extends Clonable<T>>*/(/*=T*/ object) {
3716 if (/*info:NON_GROUND_TYPE_CHECK_INFO*/object is SubClonable/*<T>*/) {
3717 // Note we need to cast back to T, because promotion lost that type info.
3718 print(object.m(object as dynamic/*=T*/));
3719 }
3720 }
3721 ''');
3722 }
3723
3724 void test_typeSubtyping_assigningClass() {
3725 checkFile('''
3726 class A {}
3727 class B extends A {}
3728
3729 void main() {
3730 dynamic y;
3731 Object o;
3732 int i = 0;
3733 double d = 0.0;
3734 num n;
3735 A a;
3736 B b;
3737 y = a;
3738 o = a;
3739 i = /*error:INVALID_ASSIGNMENT*/a;
3740 d = /*error:INVALID_ASSIGNMENT*/a;
3741 n = /*error:INVALID_ASSIGNMENT*/a;
3742 a = a;
3743 b = /*info:DOWN_CAST_IMPLICIT*/a;
3744 }
3745 ''');
3746 }
3747
3748 void test_typeSubtyping_assigningSubclass() {
3749 checkFile('''
3750 class A {}
3751 class B extends A {}
3752 class C extends A {}
3753
3754 void main() {
3755 dynamic y;
3756 Object o;
3757 int i = 0;
3758 double d = 0.0;
3759 num n;
3760 A a;
3761 B b;
3762 C c;
3763 y = b;
3764 o = b;
3765 i = /*error:INVALID_ASSIGNMENT*/b;
3766 d = /*error:INVALID_ASSIGNMENT*/b;
3767 n = /*error:INVALID_ASSIGNMENT*/b;
3768 a = b;
3769 b = b;
3770 c = /*error:INVALID_ASSIGNMENT*/b;
3771 }
3772 ''');
3773 }
3774
3775 void test_typeSubtyping_dynamicDowncasts() {
3776 checkFile('''
3777 class A {}
3778 class B extends A {}
3779
3780 void main() {
3781 dynamic y;
3782 Object o;
3783 int i = 0;
3784 double d = 0.0;
3785 num n;
3786 A a;
3787 B b;
3788 o = y;
3789 i = /*info:DYNAMIC_CAST*/y;
3790 d = /*info:DYNAMIC_CAST*/y;
3791 n = /*info:DYNAMIC_CAST*/y;
3792 a = /*info:DYNAMIC_CAST*/y;
3793 b = /*info:DYNAMIC_CAST*/y;
3794 }
3795 ''');
3796 }
3797
3798 void test_typeSubtyping_dynamicIsTop() {
3799 checkFile('''
3800 class A {}
3801 class B extends A {}
3802
3803 void main() {
3804 dynamic y;
3805 Object o;
3806 int i = 0;
3807 double d = 0.0;
3808 num n;
3809 A a;
3810 B b;
3811 y = o;
3812 y = i;
3813 y = d;
3814 y = n;
3815 y = a;
3816 y = b;
3817 }
3818 ''');
3819 }
3820
3821 void test_typeSubtyping_interfaces() {
3822 checkFile('''
3823 class A {}
3824 class B extends A {}
3825 class C extends A {}
3826 class D extends B implements C {}
3827
3828 void main() {
3829 A top;
3830 B left;
3831 C right;
3832 D bot;
3833 {
3834 top = top;
3835 top = left;
3836 top = right;
3837 top = bot;
3838 }
3839 {
3840 left = /*info:DOWN_CAST_IMPLICIT*/top;
3841 left = left;
3842 left = /*error:INVALID_ASSIGNMENT*/right;
3843 left = bot;
3844 }
3845 {
3846 right = /*info:DOWN_CAST_IMPLICIT*/top;
3847 right = /*error:INVALID_ASSIGNMENT*/left;
3848 right = right;
3849 right = bot;
3850 }
3851 {
3852 bot = /*info:DOWN_CAST_IMPLICIT*/top;
3853 bot = /*info:DOWN_CAST_IMPLICIT*/left;
3854 bot = /*info:DOWN_CAST_IMPLICIT*/right;
3855 bot = bot;
3856 }
3857 }
3858 ''');
3859 }
3860
3861 void test_unaryOperators() {
3862 checkFile('''
3863 class A {
3864 A operator ~() => null;
3865 A operator +(int x) => null;
3866 A operator -(int x) => null;
3867 A operator -() => null;
3868 }
3869 class B extends A {}
3870 class C extends B {}
3871
3872 foo() => new A();
3873
3874 test() {
3875 A a = new A();
3876 B b = new B();
3877 var c = foo();
3878 dynamic d;
3879
3880 ~a;
3881 (/*info:DYNAMIC_INVOKE*/~d);
3882
3883 !/*error:NON_BOOL_NEGATION_EXPRESSION*/a;
3884 !/*info:DYNAMIC_CAST*/d;
3885
3886 -a;
3887 (/*info:DYNAMIC_INVOKE*/-d);
3888
3889 ++a;
3890 --a;
3891 (/*info:DYNAMIC_INVOKE*/++d);
3892 (/*info:DYNAMIC_INVOKE*/--d);
3893
3894 a++;
3895 a--;
3896 (/*info:DYNAMIC_INVOKE*/d++);
3897 (/*info:DYNAMIC_INVOKE*/d--);
3898
3899 ++/*info:DOWN_CAST_IMPLICIT_ASSIGN*/b;
3900 --/*info:DOWN_CAST_IMPLICIT_ASSIGN*/b;
3901 /*info:DOWN_CAST_IMPLICIT_ASSIGN*/b++;
3902 /*info:DOWN_CAST_IMPLICIT_ASSIGN*/b--;
3903
3904 takesC(C c) => null;
3905 takesC(/*info:DOWN_CAST_IMPLICIT*/++/*info:DOWN_CAST_IMPLICIT_ASSIGN*/b);
3906 takesC(/*info:DOWN_CAST_IMPLICIT*/--/*info:DOWN_CAST_IMPLICIT_ASSIGN*/b);
3907 takesC(/*info:DOWN_CAST_IMPLICIT,info:DOWN_CAST_IMPLICIT_ASSIGN*/b++);
3908 takesC(/*info:DOWN_CAST_IMPLICIT,info:DOWN_CAST_IMPLICIT_ASSIGN*/b--);
3909 }''');
3910 }
3911
3912 void test_unboundRedirectingConstructor() {
3913 // This is a regression test for https://github.com/dart-lang/sdk/issues/250 71
3914 checkFile('''
3915 class Foo {
3916 Foo() : /*error:REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR*/this.init();
3917 }
3918 ''');
3919 }
3920
3921 void test_unboundTypeName() {
3922 checkFile('''
3923 void main() {
3924 /*error:UNDEFINED_CLASS*/AToB y;
3925 }
3926 ''');
3927 }
3928
3929 void test_unboundVariable() {
3930 checkFile('''
3931 void main() {
3932 dynamic y = /*error:UNDEFINED_IDENTIFIER*/unboundVariable;
3933 }
3934 ''');
3935 }
3936
3937 void test_voidSubtyping() {
3938 // Regression test for https://github.com/dart-lang/sdk/issues/25069
3939 checkFile('''
3940 typedef int Foo();
3941 void foo() {}
3942 void main () {
3943 Foo x = /*error:INVALID_ASSIGNMENT,info:USE_OF_VOID_RESULT*/foo();
3944 }
3945 ''');
3946 }
3947 }
3948
3949 void _addMetaLibrary() {
3950 addFile(r'''
3951 library meta;
3952 class _Checked { const _Checked(); }
3953 const Object checked = const _Checked();
3954
3955 class _Virtual { const _Virtual(); }
3956 const Object virtual = const _Virtual();
3957 ''', name: '/meta.dart');
3958 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698