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

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

Issue 1273343002: fix testChecker to include test inside (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 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
« no previous file with comments | « test/checker/checker_test.dart ('k') | test/testing.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 /// Tests for type inference. 5 /// Tests for type inference.
6 library dev_compiler.test.inferred_type_test; 6 library dev_compiler.test.inferred_type_test;
7 7
8 import 'package:test/test.dart'; 8 import 'package:test/test.dart';
9 9
10 import '../testing.dart'; 10 import '../testing.dart';
11 11
12 void main() { 12 void main() {
13 test('infer type on var', () { 13 // Error also expected when declared type is `int`.
14 // Error also expected when declared type is `int`. 14 testChecker('infer type on var', {
15 testChecker({ 15 '/main.dart': '''
16 '/main.dart': '''
17 test1() { 16 test1() {
18 int x = 3; 17 int x = 3;
19 x = /*severe:StaticTypeError*/"hi"; 18 x = /*severe:StaticTypeError*/"hi";
20 } 19 }
21 ''' 20 '''
22 }); 21 });
23 22
24 // If inferred type is `int`, error is also reported 23 // If inferred type is `int`, error is also reported
25 testChecker({ 24 testChecker('infer type on var 2', {
26 '/main.dart': ''' 25 '/main.dart': '''
27 test2() { 26 test2() {
28 var x = 3; 27 var x = 3;
29 x = /*severe:StaticTypeError*/"hi"; 28 x = /*severe:StaticTypeError*/"hi";
30 } 29 }
31 ''' 30 '''
32 });
33 }); 31 });
34 32
35 test('Error when declared type is `int` and assigned null.', () { 33 testChecker('Error when declared type is `int` and assigned null.', {
36 testChecker({ 34 '/main.dart': '''
37 '/main.dart': '''
38 test1() { 35 test1() {
39 int x = 3; 36 int x = 3;
40 x = /*severe:StaticTypeError*/null; 37 x = /*severe:StaticTypeError*/null;
41 } 38 }
42 ''' 39 '''
43 }, nonnullableTypes: <String>[ 40 }, nonnullableTypes: <String>[
44 'int', 41 'int',
45 'double' 42 'double'
46 ]); 43 ]);
47 });
48 44
49 test('Error when inferred type is `int` and assigned null.', () { 45 testChecker('Error when inferred type is `int` and assigned null.', {
50 testChecker({ 46 '/main.dart': '''
51 '/main.dart': '''
52 test1() { 47 test1() {
53 var x = 3; 48 var x = 3;
54 x = /*severe:StaticTypeError*/null; 49 x = /*severe:StaticTypeError*/null;
55 } 50 }
56 ''' 51 '''
57 }, nonnullableTypes: <String>[ 52 }, nonnullableTypes: <String>[
58 'int', 53 'int',
59 'double' 54 'double'
60 ]); 55 ]);
61 });
62 56
63 test('No error when declared type is `num` and assigned null.', () { 57 testChecker('No error when declared type is `num` and assigned null.', {
64 testChecker({ 58 '/main.dart': '''
65 '/main.dart': '''
66 test1() { 59 test1() {
67 num x = 3; 60 num x = 3;
68 x = null; 61 x = null;
69 } 62 }
70 ''' 63 '''
71 });
72 }); 64 });
73 65
74 test('do not infer type on dynamic', () { 66 testChecker('do not infer type on dynamic', {
75 testChecker({ 67 '/main.dart': '''
76 '/main.dart': '''
77 test() { 68 test() {
78 dynamic x = 3; 69 dynamic x = 3;
79 x = "hi"; 70 x = "hi";
80 } 71 }
81 ''' 72 '''
82 });
83 }); 73 });
84 74
85 test('do not infer type when initializer is null', () { 75 testChecker('do not infer type when initializer is null', {
86 testChecker({ 76 '/main.dart': '''
87 '/main.dart': '''
88 test() { 77 test() {
89 var x = null; 78 var x = null;
90 x = "hi"; 79 x = "hi";
91 x = 3; 80 x = 3;
92 } 81 }
93 ''' 82 '''
94 });
95 }); 83 });
96 84
97 test('infer type on var from field', () { 85 testChecker('infer type on var from field', {
98 testChecker({ 86 '/main.dart': '''
99 '/main.dart': '''
100 class A { 87 class A {
101 int x = 0; 88 int x = 0;
102 89
103 test1() { 90 test1() {
104 var a = x; 91 var a = x;
105 a = /*severe:StaticTypeError*/"hi"; 92 a = /*severe:StaticTypeError*/"hi";
106 a = 3; 93 a = 3;
107 var b = y; 94 var b = y;
108 b = /*severe:StaticTypeError*/"hi"; 95 b = /*severe:StaticTypeError*/"hi";
109 b = 4; 96 b = 4;
110 var c = z; 97 var c = z;
111 c = /*severe:StaticTypeError*/"hi"; 98 c = /*severe:StaticTypeError*/"hi";
112 c = 4; 99 c = 4;
113 } 100 }
114 101
115 int y; // field def after use 102 int y; // field def after use
116 final z = 42; // should infer `int` 103 final z = 42; // should infer `int`
117 } 104 }
118 ''' 105 '''
119 });
120 }); 106 });
121 107
122 test('infer type on var from top-level', () { 108 testChecker('infer type on var from top-level', {
123 testChecker({ 109 '/main.dart': '''
124 '/main.dart': '''
125 int x = 0; 110 int x = 0;
126 111
127 test1() { 112 test1() {
128 var a = x; 113 var a = x;
129 a = /*severe:StaticTypeError*/"hi"; 114 a = /*severe:StaticTypeError*/"hi";
130 a = 3; 115 a = 3;
131 var b = y; 116 var b = y;
132 b = /*severe:StaticTypeError*/"hi"; 117 b = /*severe:StaticTypeError*/"hi";
133 b = 4; 118 b = 4;
134 var c = z; 119 var c = z;
135 c = /*severe:StaticTypeError*/"hi"; 120 c = /*severe:StaticTypeError*/"hi";
136 c = 4; 121 c = 4;
137 } 122 }
138 123
139 int y = 0; // field def after use 124 int y = 0; // field def after use
140 final z = 42; // should infer `int` 125 final z = 42; // should infer `int`
141 ''' 126 '''
142 });
143 }); 127 });
144 128
145 test('do not infer field type when initializer is null', () { 129 testChecker('do not infer field type when initializer is null', {
146 testChecker({ 130 '/main.dart': '''
147 '/main.dart': '''
148 var x = null; 131 var x = null;
149 var y = 3; 132 var y = 3;
150 class A { 133 class A {
151 static var x = null; 134 static var x = null;
152 static var y = 3; 135 static var y = 3;
153 136
154 var x2 = null; 137 var x2 = null;
155 var y2 = 3; 138 var y2 = 3;
156 } 139 }
157 140
158 test() { 141 test() {
159 x = "hi"; 142 x = "hi";
160 y = /*severe:StaticTypeError*/"hi"; 143 y = /*severe:StaticTypeError*/"hi";
161 A.x = "hi"; 144 A.x = "hi";
162 A.y = /*severe:StaticTypeError*/"hi"; 145 A.y = /*severe:StaticTypeError*/"hi";
163 new A().x2 = "hi"; 146 new A().x2 = "hi";
164 new A().y2 = /*severe:StaticTypeError*/"hi"; 147 new A().y2 = /*severe:StaticTypeError*/"hi";
165 } 148 }
166 ''' 149 '''
167 });
168 }); 150 });
169 151
170 test('do not infer from variables if flag is off', () { 152 testChecker(
171 testChecker({ 153 'do not infer from variables if flag is off',
172 '/main.dart': ''' 154 {
155 '/main.dart': '''
173 var x = 2; 156 var x = 2;
174 var y = x; 157 var y = x;
175 158
176 test1() { 159 test1() {
177 x = /*severe:StaticTypeError*/"hi"; 160 x = /*severe:StaticTypeError*/"hi";
178 y = "hi"; 161 y = "hi";
179 } 162 }
180 ''' 163 '''
181 }, inferTransitively: false); 164 },
165 inferTransitively: false);
182 166
183 testChecker({ 167 testChecker(
184 '/main.dart': ''' 168 'do not infer from variables if flag is off 2',
169 {
170 '/main.dart': '''
185 class A { 171 class A {
186 static var x = 2; 172 static var x = 2;
187 static var y = A.x; 173 static var y = A.x;
188 } 174 }
189 175
190 test1() { 176 test1() {
191 A.x = /*severe:StaticTypeError*/"hi"; 177 A.x = /*severe:StaticTypeError*/"hi";
192 A.y = "hi"; 178 A.y = "hi";
193 } 179 }
194 ''' 180 '''
195 }, inferTransitively: false); 181 },
196 }); 182 inferTransitively: false);
197 183
198 test('do not infer from variables in non-cycle imports if flag is off', () { 184 testChecker(
199 testChecker({ 185 'do not infer from variables in non-cycle imports if flag is off',
200 '/a.dart': ''' 186 {
187 '/a.dart': '''
201 var x = 2; 188 var x = 2;
202 ''', 189 ''',
203 '/main.dart': ''' 190 '/main.dart': '''
204 import 'a.dart'; 191 import 'a.dart';
205 var y = x; 192 var y = x;
206 193
207 test1() { 194 test1() {
208 x = /*severe:StaticTypeError*/"hi"; 195 x = /*severe:StaticTypeError*/"hi";
209 y = "hi"; 196 y = "hi";
210 } 197 }
211 ''' 198 '''
212 }, inferTransitively: false); 199 },
200 inferTransitively: false);
213 201
214 testChecker({ 202 testChecker(
215 '/a.dart': ''' 203 'do not infer from variables in non-cycle imports if flag is off 2',
204 {
205 '/a.dart': '''
216 class A { static var x = 2; } 206 class A { static var x = 2; }
217 ''', 207 ''',
218 '/main.dart': ''' 208 '/main.dart': '''
219 import 'a.dart'; 209 import 'a.dart';
220 class B { static var y = A.x; } 210 class B { static var y = A.x; }
221 211
222 test1() { 212 test1() {
223 A.x = /*severe:StaticTypeError*/"hi"; 213 A.x = /*severe:StaticTypeError*/"hi";
224 B.y = "hi"; 214 B.y = "hi";
225 } 215 }
226 ''' 216 '''
227 }, inferTransitively: false); 217 },
228 }); 218 inferTransitively: false);
229 219
230 test('infer from variables in non-cycle imports with flag', () { 220 testChecker(
231 testChecker({ 221 'infer from variables in non-cycle imports with flag',
232 '/a.dart': ''' 222 {
223 '/a.dart': '''
233 var x = 2; 224 var x = 2;
234 ''', 225 ''',
235 '/main.dart': ''' 226 '/main.dart': '''
236 import 'a.dart'; 227 import 'a.dart';
237 var y = x; 228 var y = x;
238 229
239 test1() { 230 test1() {
240 x = /*severe:StaticTypeError*/"hi"; 231 x = /*severe:StaticTypeError*/"hi";
241 y = /*severe:StaticTypeError*/"hi"; 232 y = /*severe:StaticTypeError*/"hi";
242 } 233 }
243 ''' 234 '''
244 }, inferTransitively: true); 235 },
236 inferTransitively: true);
245 237
246 testChecker({ 238 testChecker(
247 '/a.dart': ''' 239 'infer from variables in non-cycle imports with flag 2',
240 {
241 '/a.dart': '''
248 class A { static var x = 2; } 242 class A { static var x = 2; }
249 ''', 243 ''',
250 '/main.dart': ''' 244 '/main.dart': '''
251 import 'a.dart'; 245 import 'a.dart';
252 class B { static var y = A.x; } 246 class B { static var y = A.x; }
253 247
254 test1() { 248 test1() {
255 A.x = /*severe:StaticTypeError*/"hi"; 249 A.x = /*severe:StaticTypeError*/"hi";
256 B.y = /*severe:StaticTypeError*/"hi"; 250 B.y = /*severe:StaticTypeError*/"hi";
257 } 251 }
258 ''' 252 '''
259 }, inferTransitively: true); 253 },
260 }); 254 inferTransitively: true);
261 255
262 test('do not infer from variables in cycle libs when flag is off', () { 256 testChecker(
263 testChecker({ 257 'do not infer from variables in cycle libs when flag is off',
264 '/a.dart': ''' 258 {
259 '/a.dart': '''
265 import 'main.dart'; 260 import 'main.dart';
266 var x = 2; // ok to infer 261 var x = 2; // ok to infer
267 ''', 262 ''',
268 '/main.dart': ''' 263 '/main.dart': '''
269 import 'a.dart'; 264 import 'a.dart';
270 var y = x; // not ok to infer yet 265 var y = x; // not ok to infer yet
271 266
272 test1() { 267 test1() {
273 int t = 3; 268 int t = 3;
274 t = x; 269 t = x;
275 t = /*info:DynamicCast*/y; 270 t = /*info:DynamicCast*/y;
276 } 271 }
277 ''' 272 '''
278 }, inferTransitively: false); 273 },
274 inferTransitively: false);
279 275
280 testChecker({ 276 testChecker(
281 '/a.dart': ''' 277 'do not infer from variables in cycle libs when flag is off 2',
278 {
279 '/a.dart': '''
282 import 'main.dart'; 280 import 'main.dart';
283 class A { static var x = 2; } 281 class A { static var x = 2; }
284 ''', 282 ''',
285 '/main.dart': ''' 283 '/main.dart': '''
286 import 'a.dart'; 284 import 'a.dart';
287 class B { static var y = A.x; } 285 class B { static var y = A.x; }
288 286
289 test1() { 287 test1() {
290 int t = 3; 288 int t = 3;
291 t = A.x; 289 t = A.x;
292 t = /*info:DynamicCast*/B.y; 290 t = /*info:DynamicCast*/B.y;
293 } 291 }
294 ''' 292 '''
295 }, inferTransitively: false); 293 },
296 }); 294 inferTransitively: false);
297 295
298 test('infer from variables in cycle libs when flag is on', () { 296 testChecker(
299 testChecker({ 297 'infer from variables in cycle libs when flag is on',
300 '/a.dart': ''' 298 {
299 '/a.dart': '''
301 import 'main.dart'; 300 import 'main.dart';
302 var x = 2; // ok to infer 301 var x = 2; // ok to infer
303 ''', 302 ''',
304 '/main.dart': ''' 303 '/main.dart': '''
305 import 'a.dart'; 304 import 'a.dart';
306 var y = x; // now ok :) 305 var y = x; // now ok :)
307 306
308 test1() { 307 test1() {
309 int t = 3; 308 int t = 3;
310 t = x; 309 t = x;
311 t = y; 310 t = y;
312 } 311 }
313 ''' 312 '''
314 }, inferTransitively: true); 313 },
314 inferTransitively: true);
315 315
316 testChecker({ 316 testChecker(
317 '/a.dart': ''' 317 'infer from variables in cycle libs when flag is on 2',
318 {
319 '/a.dart': '''
318 import 'main.dart'; 320 import 'main.dart';
319 class A { static var x = 2; } 321 class A { static var x = 2; }
320 ''', 322 ''',
321 '/main.dart': ''' 323 '/main.dart': '''
322 import 'a.dart'; 324 import 'a.dart';
323 class B { static var y = A.x; } 325 class B { static var y = A.x; }
324 326
325 test1() { 327 test1() {
326 int t = 3; 328 int t = 3;
327 t = A.x; 329 t = A.x;
328 t = B.y; 330 t = B.y;
329 } 331 }
330 ''' 332 '''
331 }, inferTransitively: true); 333 },
332 }); 334 inferTransitively: true);
333 335
334 test('do not infer from static and instance fields when flag is off', () { 336 testChecker(
335 testChecker({ 337 'do not infer from static and instance fields when flag is off',
336 '/a.dart': ''' 338 {
339 '/a.dart': '''
337 import 'b.dart'; 340 import 'b.dart';
338 class A { 341 class A {
339 static final a1 = B.b1; 342 static final a1 = B.b1;
340 final a2 = new B().b2; 343 final a2 = new B().b2;
341 } 344 }
342 ''', 345 ''',
343 '/b.dart': ''' 346 '/b.dart': '''
344 class B { 347 class B {
345 static final b1 = 1; 348 static final b1 = 1;
346 final b2 = 1; 349 final b2 = 1;
347 } 350 }
348 ''', 351 ''',
349 '/main.dart': ''' 352 '/main.dart': '''
350 import "a.dart"; 353 import "a.dart";
351 354
352 test1() { 355 test1() {
353 int x = 0; 356 int x = 0;
354 // inference in A disabled (flag is off) 357 // inference in A disabled (flag is off)
355 x = /*info:DynamicCast*/A.a1; 358 x = /*info:DynamicCast*/A.a1;
356 x = /*info:DynamicCast*/new A().a2; 359 x = /*info:DynamicCast*/new A().a2;
357 } 360 }
358 ''' 361 '''
359 }, inferTransitively: false); 362 },
360 }); 363 inferTransitively: false);
361 364
362 test('can infer also from static and instance fields (flag on)', () { 365 testChecker(
363 testChecker({ 366 'can infer also from static and instance fields (flag on)',
364 '/a.dart': ''' 367 {
368 '/a.dart': '''
365 import 'b.dart'; 369 import 'b.dart';
366 class A { 370 class A {
367 static final a1 = B.b1; 371 static final a1 = B.b1;
368 final a2 = new B().b2; 372 final a2 = new B().b2;
369 } 373 }
370 ''', 374 ''',
371 '/b.dart': ''' 375 '/b.dart': '''
372 class B { 376 class B {
373 static final b1 = 1; 377 static final b1 = 1;
374 final b2 = 1; 378 final b2 = 1;
375 } 379 }
376 ''', 380 ''',
377 '/main.dart': ''' 381 '/main.dart': '''
378 import "a.dart"; 382 import "a.dart";
379 383
380 test1() { 384 test1() {
381 int x = 0; 385 int x = 0;
382 // inference in A now works. 386 // inference in A now works.
383 x = A.a1; 387 x = A.a1;
384 x = new A().a2; 388 x = new A().a2;
385 } 389 }
386 ''' 390 '''
387 }, inferTransitively: true); 391 },
388 }); 392 inferTransitively: true);
389 393
390 test('inference in cycles is deterministic', () { 394 testChecker(
391 testChecker({ 395 'inference in cycles is deterministic',
392 '/a.dart': ''' 396 {
397 '/a.dart': '''
393 import 'b.dart'; 398 import 'b.dart';
394 class A { 399 class A {
395 static final a1 = B.b1; 400 static final a1 = B.b1;
396 final a2 = new B().b2; 401 final a2 = new B().b2;
397 } 402 }
398 ''', 403 ''',
399 '/b.dart': ''' 404 '/b.dart': '''
400 class B { 405 class B {
401 static final b1 = 1; 406 static final b1 = 1;
402 final b2 = 1; 407 final b2 = 1;
403 } 408 }
404 ''', 409 ''',
405 '/c.dart': ''' 410 '/c.dart': '''
406 import "main.dart"; // creates a cycle 411 import "main.dart"; // creates a cycle
407 412
408 class C { 413 class C {
409 static final c1 = 1; 414 static final c1 = 1;
410 final c2 = 1; 415 final c2 = 1;
411 } 416 }
412 ''', 417 ''',
413 '/e.dart': ''' 418 '/e.dart': '''
414 import 'a.dart'; 419 import 'a.dart';
415 part 'e2.dart'; 420 part 'e2.dart';
416 421
417 class E { 422 class E {
418 static final e1 = 1; 423 static final e1 = 1;
419 static final e2 = F.f1; 424 static final e2 = F.f1;
420 static final e3 = A.a1; 425 static final e3 = A.a1;
421 final e4 = 1; 426 final e4 = 1;
422 final e5 = new F().f2; 427 final e5 = new F().f2;
423 final e6 = new A().a2; 428 final e6 = new A().a2;
424 } 429 }
425 ''', 430 ''',
426 '/f.dart': ''' 431 '/f.dart': '''
427 part 'f2.dart'; 432 part 'f2.dart';
428 ''', 433 ''',
429 '/e2.dart': ''' 434 '/e2.dart': '''
430 class F { 435 class F {
431 static final f1 = 1; 436 static final f1 = 1;
432 final f2 = 1; 437 final f2 = 1;
433 } 438 }
434 ''', 439 ''',
435 '/main.dart': ''' 440 '/main.dart': '''
436 import "a.dart"; 441 import "a.dart";
437 import "c.dart"; 442 import "c.dart";
438 import "e.dart"; 443 import "e.dart";
439 444
440 class D { 445 class D {
441 static final d1 = A.a1 + 1; 446 static final d1 = A.a1 + 1;
442 static final d2 = C.c1 + 1; 447 static final d2 = C.c1 + 1;
443 final d3 = new A().a2; 448 final d3 = new A().a2;
444 final d4 = new C().c2; 449 final d4 = new C().c2;
445 } 450 }
(...skipping 18 matching lines...) Expand all
464 x = E.e1; 469 x = E.e1;
465 x = E.e2; 470 x = E.e2;
466 x = E.e3; 471 x = E.e3;
467 x = new E().e4; 472 x = new E().e4;
468 x = /*info:DynamicCast*/new E().e5; 473 x = /*info:DynamicCast*/new E().e5;
469 x = new E().e6; 474 x = new E().e6;
470 x = F.f1; 475 x = F.f1;
471 x = new F().f2; 476 x = new F().f2;
472 } 477 }
473 ''' 478 '''
474 }, inferTransitively: true); 479 },
475 }); 480 inferTransitively: true);
476 481
477 test('infer from complex expressions if the outer-most value is precise', () { 482 testChecker(
478 testChecker({ 483 'infer from complex expressions if the outer-most value is precise', {
479 '/main.dart': ''' 484 '/main.dart': '''
480 class A { int x; B operator+(other) {} } 485 class A { int x; B operator+(other) {} }
481 class B extends A { B(ignore); } 486 class B extends A { B(ignore); }
482 var a = new A(); 487 var a = new A();
483 // Note: it doesn't matter that some of these refer to 'x'. 488 // Note: it doesn't matter that some of these refer to 'x'.
484 var b = new B(x); // allocations 489 var b = new B(x); // allocations
485 var c1 = [x]; // list literals 490 var c1 = [x]; // list literals
486 var c2 = const []; 491 var c2 = const [];
487 var d = {'a': 'b'}; // map literals 492 var d = {'a': 'b'}; // map literals
488 var e = new A()..x = 3; // cascades 493 var e = new A()..x = 3; // cascades
489 var f = 2 + 3; // binary expressions are OK if the left operand 494 var f = 2 + 3; // binary expressions are OK if the left operand
(...skipping 22 matching lines...) Expand all
512 g = 1; 517 g = 1;
513 g = /*severe:StaticTypeError*/false; 518 g = /*severe:StaticTypeError*/false;
514 h = /*severe:StaticTypeError*/false; 519 h = /*severe:StaticTypeError*/false;
515 h = new B(); 520 h = new B();
516 i = false; 521 i = false;
517 j = new B(); 522 j = new B();
518 j = /*severe:StaticTypeError*/false; 523 j = /*severe:StaticTypeError*/false;
519 j = /*severe:StaticTypeError*/[]; 524 j = /*severe:StaticTypeError*/[];
520 } 525 }
521 ''' 526 '''
522 });
523 }); 527 });
524 528
525 test('do not infer if complex expressions read possibly inferred field', () { 529 testChecker(
526 testChecker({ 530 'do not infer if complex expressions read possibly inferred field',
527 '/a.dart': ''' 531 {
532 '/a.dart': '''
528 class A { 533 class A {
529 var x = 3; 534 var x = 3;
530 } 535 }
531 ''', 536 ''',
532 '/main.dart': ''' 537 '/main.dart': '''
533 import 'a.dart'; 538 import 'a.dart';
534 class B { 539 class B {
535 var y = 3; 540 var y = 3;
536 } 541 }
537 final t1 = new A(); 542 final t1 = new A();
538 final t2 = new A().x; 543 final t2 = new A().x;
539 final t3 = new B(); 544 final t3 = new B();
540 final t4 = new B().y; 545 final t4 = new B().y;
541 546
542 test1() { 547 test1() {
543 int i = 0; 548 int i = 0;
544 A a; 549 A a;
545 B b; 550 B b;
546 a = t1; 551 a = t1;
547 i = /*info:DynamicCast*/t2; 552 i = /*info:DynamicCast*/t2;
548 b = t3; 553 b = t3;
549 i = /*info:DynamicCast*/t4; 554 i = /*info:DynamicCast*/t4;
550 i = new B().y; // B.y was inferred though 555 i = new B().y; // B.y was inferred though
551 } 556 }
552 ''' 557 '''
553 }, inferTransitively: false); 558 },
559 inferTransitively: false);
554 560
555 // but flags can enable this behavior. 561 // but flags can enable this behavior.
556 testChecker({ 562 testChecker(
557 '/a.dart': ''' 563 'infer if complex expressions read possibly inferred field',
564 {
565 '/a.dart': '''
558 class A { 566 class A {
559 var x = 3; 567 var x = 3;
560 } 568 }
561 ''', 569 ''',
562 '/main.dart': ''' 570 '/main.dart': '''
563 import 'a.dart'; 571 import 'a.dart';
564 class B { 572 class B {
565 var y = 3; 573 var y = 3;
566 } 574 }
567 final t1 = new A(); 575 final t1 = new A();
568 final t2 = new A().x; 576 final t2 = new A().x;
569 final t3 = new B(); 577 final t3 = new B();
570 final t4 = new B().y; 578 final t4 = new B().y;
571 579
572 test1() { 580 test1() {
573 int i = 0; 581 int i = 0;
574 A a; 582 A a;
575 B b; 583 B b;
576 a = t1; 584 a = t1;
577 i = t2; 585 i = t2;
578 b = t3; 586 b = t3;
579 i = /*info:DynamicCast*/t4; 587 i = /*info:DynamicCast*/t4;
580 i = new B().y; // B.y was inferred though 588 i = new B().y; // B.y was inferred though
581 } 589 }
582 ''' 590 '''
583 }, inferTransitively: true); 591 },
584 }); 592 inferTransitively: true);
585 593
586 test('infer types on loop indices', () { 594 group('infer types on loop indices', () {
587 // foreach loop 595 testChecker('foreach loop', {
588 testChecker({
589 '/main.dart': ''' 596 '/main.dart': '''
590 class Foo { 597 class Foo {
591 int bar = 42; 598 int bar = 42;
592 } 599 }
593 600
594 test() { 601 test() {
595 var list = <Foo>[]; 602 var list = <Foo>[];
596 for (var x in list) { 603 for (var x in list) {
597 String y = /*severe:StaticTypeError*/x; 604 String y = /*severe:StaticTypeError*/x;
598 } 605 }
(...skipping 29 matching lines...) Expand all
628 635
629 // We're not properly inferring that map.keys is an Iterable<String> 636 // We're not properly inferring that map.keys is an Iterable<String>
630 // and that x is a String. 637 // and that x is a String.
631 for (var x in map.keys) { 638 for (var x in map.keys) {
632 String y = x; 639 String y = x;
633 } 640 }
634 } 641 }
635 ''' 642 '''
636 }); 643 });
637 644
638 // for loop, with inference 645 testChecker('for loop, with inference', {
639 testChecker({
640 '/main.dart': ''' 646 '/main.dart': '''
641 test() { 647 test() {
642 for (var i = 0; i < 10; i++) { 648 for (var i = 0; i < 10; i++) {
643 int j = i + 1; 649 int j = i + 1;
644 } 650 }
645 } 651 }
646 ''' 652 '''
647 }); 653 });
648 }); 654 });
649 655
650 test('propagate inference to field in class', () { 656 testChecker('propagate inference to field in class', {
651 testChecker({ 657 '/main.dart': '''
652 '/main.dart': '''
653 class A { 658 class A {
654 int x = 2; 659 int x = 2;
655 } 660 }
656 661
657 test() { 662 test() {
658 var a = new A(); 663 var a = new A();
659 A b = a; // doesn't require down cast 664 A b = a; // doesn't require down cast
660 print(a.x); // doesn't require dynamic invoke 665 print(a.x); // doesn't require dynamic invoke
661 print(a.x + 2); // ok to use in bigger expression 666 print(a.x + 2); // ok to use in bigger expression
662 } 667 }
663 ''' 668 '''
664 }); 669 });
665 670
666 // Same code with dynamic yields warnings 671 testChecker('propagate inference to field in class dynamic warnings', {
667 testChecker({ 672 '/main.dart': '''
668 '/main.dart': '''
669 class A { 673 class A {
670 int x = 2; 674 int x = 2;
671 } 675 }
672 676
673 test() { 677 test() {
674 dynamic a = new A(); 678 dynamic a = new A();
675 A b = /*info:DynamicCast*/a; 679 A b = /*info:DynamicCast*/a;
676 print(/*info:DynamicInvoke*/a.x); 680 print(/*info:DynamicInvoke*/a.x);
677 print(/*info:DynamicInvoke*/(/*info:DynamicInvoke*/a.x) + 2); 681 print(/*info:DynamicInvoke*/(/*info:DynamicInvoke*/a.x) + 2);
678 } 682 }
679 ''' 683 '''
680 });
681 }); 684 });
682 685
683 test('propagate inference transitively ', () { 686 testChecker('propagate inference transitively', {
684 testChecker({ 687 '/main.dart': '''
685 '/main.dart': '''
686 class A { 688 class A {
687 int x = 2; 689 int x = 2;
688 } 690 }
689 691
690 test5() { 692 test5() {
691 var a1 = new A(); 693 var a1 = new A();
692 a1.x = /*severe:StaticTypeError*/"hi"; 694 a1.x = /*severe:StaticTypeError*/"hi";
693 695
694 A a2 = new A(); 696 A a2 = new A();
695 a2.x = /*severe:StaticTypeError*/"hi"; 697 a2.x = /*severe:StaticTypeError*/"hi";
696 } 698 }
697 ''' 699 '''
698 }); 700 });
699 701
700 testChecker({ 702 testChecker('propagate inference transitively 2', {
701 '/main.dart': ''' 703 '/main.dart': '''
702 class A { 704 class A {
703 int x = 42; 705 int x = 42;
704 } 706 }
705 707
706 class B { 708 class B {
707 A a = new A(); 709 A a = new A();
708 } 710 }
709 711
710 class C { 712 class C {
711 B b = new B(); 713 B b = new B();
712 } 714 }
713 715
714 class D { 716 class D {
715 C c = new C(); 717 C c = new C();
716 } 718 }
717 719
718 void main() { 720 void main() {
719 var d1 = new D(); 721 var d1 = new D();
720 print(d1.c.b.a.x); 722 print(d1.c.b.a.x);
721 723
722 D d2 = new D(); 724 D d2 = new D();
723 print(d2.c.b.a.x); 725 print(d2.c.b.a.x);
724 } 726 }
725 ''' 727 '''
726 });
727 }); 728 });
728 729
729 test('infer type on overridden fields', () { 730 group('infer type on overridden fields', () {
730 testChecker({ 731 testChecker(
731 '/main.dart': ''' 732 '1',
733 {
734 '/main.dart': '''
732 class A { 735 class A {
733 int x = 2; 736 int x = 2;
734 } 737 }
735 738
736 class B extends A { 739 class B extends A {
737 /*severe:InferableOverride*/get x => 3; 740 /*severe:InferableOverride*/get x => 3;
738 } 741 }
739 742
740 foo() { 743 foo() {
741 String y = /*info:DynamicCast*/new B().x; 744 String y = /*info:DynamicCast*/new B().x;
742 int z = /*info:DynamicCast*/new B().x; 745 int z = /*info:DynamicCast*/new B().x;
743 } 746 }
744 ''' 747 '''
745 }, inferFromOverrides: false); 748 },
749 inferFromOverrides: false);
746 750
747 testChecker({ 751 testChecker(
748 '/main.dart': ''' 752 '2',
753 {
754 '/main.dart': '''
749 class A { 755 class A {
750 int x = 2; 756 int x = 2;
751 } 757 }
752 758
753 class B extends A { 759 class B extends A {
754 get x => 3; 760 get x => 3;
755 } 761 }
756 762
757 foo() { 763 foo() {
758 String y = /*severe:StaticTypeError*/new B().x; 764 String y = /*severe:StaticTypeError*/new B().x;
759 int z = new B().x; 765 int z = new B().x;
760 } 766 }
761 ''' 767 '''
762 }, inferFromOverrides: true); 768 },
769 inferFromOverrides: true);
763 770
764 testChecker({ 771 testChecker(
765 '/main.dart': ''' 772 '3',
773 {
774 '/main.dart': '''
766 class A { 775 class A {
767 int x = 2; 776 int x = 2;
768 } 777 }
769 778
770 class B implements A { 779 class B implements A {
771 /*severe:InferableOverride*/get x => 3; 780 /*severe:InferableOverride*/get x => 3;
772 } 781 }
773 782
774 foo() { 783 foo() {
775 String y = /*info:DynamicCast*/new B().x; 784 String y = /*info:DynamicCast*/new B().x;
776 int z = /*info:DynamicCast*/new B().x; 785 int z = /*info:DynamicCast*/new B().x;
777 } 786 }
778 ''' 787 '''
779 }, inferFromOverrides: false); 788 },
789 inferFromOverrides: false);
780 790
781 testChecker({ 791 testChecker(
782 '/main.dart': ''' 792 '4',
793 {
794 '/main.dart': '''
783 class A { 795 class A {
784 int x = 2; 796 int x = 2;
785 } 797 }
786 798
787 class B implements A { 799 class B implements A {
788 get x => 3; 800 get x => 3;
789 } 801 }
790 802
791 foo() { 803 foo() {
792 String y = /*severe:StaticTypeError*/new B().x; 804 String y = /*severe:StaticTypeError*/new B().x;
793 int z = new B().x; 805 int z = new B().x;
794 } 806 }
795 ''' 807 '''
796 }, inferFromOverrides: true); 808 },
809 inferFromOverrides: true);
797 }); 810 });
798 811
799 test('infer types on generic instantiations', () { 812 group('infer types on generic instantiations', () {
800 for (bool infer in [true, false]) { 813 for (bool infer in [true, false]) {
801 testChecker({ 814 testChecker(
802 '/main.dart': ''' 815 'infer: $infer',
816 {
817 '/main.dart': '''
803 class A<T> { 818 class A<T> {
804 T x; 819 T x;
805 } 820 }
806 821
807 class B implements A<int> { 822 class B implements A<int> {
808 /*severe:InvalidMethodOverride*/dynamic get x => 3; 823 /*severe:InvalidMethodOverride*/dynamic get x => 3;
809 } 824 }
810 825
811 foo() { 826 foo() {
812 String y = /*info:DynamicCast*/new B().x; 827 String y = /*info:DynamicCast*/new B().x;
813 int z = /*info:DynamicCast*/new B().x; 828 int z = /*info:DynamicCast*/new B().x;
814 } 829 }
815 ''' 830 '''
816 }, inferFromOverrides: infer); 831 },
832 inferFromOverrides: infer);
817 } 833 }
818 834
819 testChecker({ 835 testChecker(
820 '/main.dart': ''' 836 '2',
837 {
838 '/main.dart': '''
821 class A<T> { 839 class A<T> {
822 T x; 840 T x;
823 } 841 }
824 842
825 class B implements A<int> { 843 class B implements A<int> {
826 /*severe:InferableOverride*/get x => 3; 844 /*severe:InferableOverride*/get x => 3;
827 } 845 }
828 846
829 foo() { 847 foo() {
830 String y = /*info:DynamicCast*/new B().x; 848 String y = /*info:DynamicCast*/new B().x;
831 int z = /*info:DynamicCast*/new B().x; 849 int z = /*info:DynamicCast*/new B().x;
832 } 850 }
833 ''' 851 '''
834 }, inferFromOverrides: false); 852 },
835 testChecker({ 853 inferFromOverrides: false);
836 '/main.dart': ''' 854
855 testChecker(
856 '3',
857 {
858 '/main.dart': '''
837 class A<T> { 859 class A<T> {
838 T x; 860 T x;
839 T w; 861 T w;
840 } 862 }
841 863
842 class B implements A<int> { 864 class B implements A<int> {
843 get x => 3; 865 get x => 3;
844 get w => /*severe:StaticTypeError*/"hello"; 866 get w => /*severe:StaticTypeError*/"hello";
845 } 867 }
846 868
847 foo() { 869 foo() {
848 String y = /*severe:StaticTypeError*/new B().x; 870 String y = /*severe:StaticTypeError*/new B().x;
849 int z = new B().x; 871 int z = new B().x;
850 } 872 }
851 ''' 873 '''
852 }, inferFromOverrides: true); 874 },
875 inferFromOverrides: true);
853 876
854 testChecker({ 877 testChecker(
855 '/main.dart': ''' 878 '4',
879 {
880 '/main.dart': '''
856 class A<T> { 881 class A<T> {
857 T x; 882 T x;
858 } 883 }
859 884
860 class B<E> extends A<E> { 885 class B<E> extends A<E> {
861 E y; 886 E y;
862 get x => y; 887 get x => y;
863 } 888 }
864 889
865 foo() { 890 foo() {
866 int y = /*severe:StaticTypeError*/new B<String>().x; 891 int y = /*severe:StaticTypeError*/new B<String>().x;
867 String z = new B<String>().x; 892 String z = new B<String>().x;
868 } 893 }
869 ''' 894 '''
870 }, inferFromOverrides: true); 895 },
896 inferFromOverrides: true);
871 897
872 testChecker({ 898 testChecker(
873 '/main.dart': ''' 899 '5',
900 {
901 '/main.dart': '''
874 abstract class I<E> { 902 abstract class I<E> {
875 String m(a, String f(v, T e)); 903 String m(a, String f(v, T e));
876 } 904 }
877 905
878 abstract class A<E> implements I<E> { 906 abstract class A<E> implements I<E> {
879 const A(); 907 const A();
880 String m(a, String f(v, T e)); 908 String m(a, String f(v, T e));
881 } 909 }
882 910
883 abstract class M { 911 abstract class M {
884 int y; 912 int y;
885 } 913 }
886 914
887 class B<E> extends A<E> implements M { 915 class B<E> extends A<E> implements M {
888 const B(); 916 const B();
889 int get y => 0; 917 int get y => 0;
890 918
891 m(a, f(v, T e)) {} 919 m(a, f(v, T e)) {}
892 } 920 }
893 921
894 foo () { 922 foo () {
895 int y = /*severe:StaticTypeError*/new B().m(null, null); 923 int y = /*severe:StaticTypeError*/new B().m(null, null);
896 String z = new B().m(null, null); 924 String z = new B().m(null, null);
897 } 925 }
898 ''' 926 '''
899 }, inferFromOverrides: true); 927 },
928 inferFromOverrides: true);
900 }); 929 });
901 930
902 test('infer type regardless of declaration order or cycles', () { 931 testChecker(
903 testChecker({ 932 'infer type regardless of declaration order or cycles',
904 '/b.dart': ''' 933 {
934 '/b.dart': '''
905 import 'main.dart'; 935 import 'main.dart';
906 936
907 class B extends A { } 937 class B extends A { }
908 ''', 938 ''',
909 '/main.dart': ''' 939 '/main.dart': '''
910 import 'b.dart'; 940 import 'b.dart';
911 class C extends B { 941 class C extends B {
912 get x; 942 get x;
913 } 943 }
914 class A { 944 class A {
915 int get x; 945 int get x;
916 } 946 }
917 foo () { 947 foo () {
918 int y = new C().x; 948 int y = new C().x;
919 String y = /*severe:StaticTypeError*/new C().x; 949 String y = /*severe:StaticTypeError*/new C().x;
920 } 950 }
921 ''' 951 '''
922 }, inferFromOverrides: true); 952 },
923 }); 953 inferFromOverrides: true);
924 954
925 // Note: this is a regression test for a non-deterministic behavior we used to 955 // Note: this is a regression test for a non-deterministic behavior we used to
926 // have with inference in library cycles. If you see this test flake out, 956 // have with inference in library cycles. If you see this test flake out,
927 // change `test` to `skip_test` and reopen bug #48. 957 // change `test` to `skip_test` and reopen bug #48.
928 test('infer types on generic instantiations in library cycle', () { 958 testChecker(
929 testChecker({ 959 'infer types on generic instantiations in library cycle',
930 '/a.dart': ''' 960 {
961 '/a.dart': '''
931 import 'main.dart'; 962 import 'main.dart';
932 abstract class I<E> { 963 abstract class I<E> {
933 A<E> m(a, String f(v, T e)); 964 A<E> m(a, String f(v, T e));
934 } 965 }
935 ''', 966 ''',
936 '/main.dart': ''' 967 '/main.dart': '''
937 import 'a.dart'; 968 import 'a.dart';
938 969
939 abstract class A<E> implements I<E> { 970 abstract class A<E> implements I<E> {
940 const A(); 971 const A();
941 972
942 E value; 973 E value;
943 } 974 }
944 975
945 abstract class M { 976 abstract class M {
946 int y; 977 int y;
947 } 978 }
948 979
949 class B<E> extends A<E> implements M { 980 class B<E> extends A<E> implements M {
950 const B(); 981 const B();
951 int get y => 0; 982 int get y => 0;
952 983
953 m(a, f(v, T e)) {} 984 m(a, f(v, T e)) {}
954 } 985 }
955 986
956 foo () { 987 foo () {
957 int y = /*severe:StaticTypeError*/new B<String>().m(null, null).value; 988 int y = /*severe:StaticTypeError*/new B<String>().m(null, null).value;
958 String z = new B<String>().m(null, null).value; 989 String z = new B<String>().m(null, null).value;
959 } 990 }
960 ''' 991 '''
961 }, inferFromOverrides: true); 992 },
962 }); 993 inferFromOverrides: true);
963 994
964 test('do not infer overridden fields that explicitly say dynamic', () { 995 group('do not infer overridden fields that explicitly say dynamic', () {
965 for (bool infer in [true, false]) { 996 for (bool infer in [true, false]) {
966 testChecker({ 997 testChecker(
967 '/main.dart': ''' 998 'infer: $infer',
999 {
1000 '/main.dart': '''
968 class A { 1001 class A {
969 int x = 2; 1002 int x = 2;
970 } 1003 }
971 1004
972 class B implements A { 1005 class B implements A {
973 /*severe:InvalidMethodOverride*/dynamic get x => 3; 1006 /*severe:InvalidMethodOverride*/dynamic get x => 3;
974 } 1007 }
975 1008
976 foo() { 1009 foo() {
977 String y = /*info:DynamicCast*/new B().x; 1010 String y = /*info:DynamicCast*/new B().x;
978 int z = /*info:DynamicCast*/new B().x; 1011 int z = /*info:DynamicCast*/new B().x;
979 } 1012 }
980 ''' 1013 '''
981 }, inferFromOverrides: infer); 1014 },
1015 inferFromOverrides: infer);
982 } 1016 }
983 }); 1017 });
984 1018
985 test('conflicts can happen', () { 1019 testChecker(
986 testChecker({ 1020 'conflicts can happen',
987 '/main.dart': ''' 1021 {
1022 '/main.dart': '''
988 class I1 { 1023 class I1 {
989 int x; 1024 int x;
990 } 1025 }
991 class I2 extends I1 { 1026 class I2 extends I1 {
992 int y; 1027 int y;
993 } 1028 }
994 1029
995 class A { 1030 class A {
996 final I1 a; 1031 final I1 a;
997 } 1032 }
998 1033
999 class B { 1034 class B {
1000 final I2 a; 1035 final I2 a;
1001 } 1036 }
1002 1037
1003 class C1 extends A implements B { 1038 class C1 extends A implements B {
1004 /*severe:InvalidMethodOverride*/get a => null; 1039 /*severe:InvalidMethodOverride*/get a => null;
1005 } 1040 }
1006 1041
1007 // Here we infer from B, which is more precise. 1042 // Here we infer from B, which is more precise.
1008 class C2 extends B implements A { 1043 class C2 extends B implements A {
1009 get a => null; 1044 get a => null;
1010 } 1045 }
1011 ''' 1046 '''
1012 }, inferFromOverrides: true); 1047 },
1048 inferFromOverrides: true);
1013 1049
1014 testChecker({ 1050 testChecker(
1015 '/main.dart': ''' 1051 'conflicts can happen 2',
1052 {
1053 '/main.dart': '''
1016 class I1 { 1054 class I1 {
1017 int x; 1055 int x;
1018 } 1056 }
1019 class I2 { 1057 class I2 {
1020 int y; 1058 int y;
1021 } 1059 }
1022 1060
1023 class I3 implements I1, I2 { 1061 class I3 implements I1, I2 {
1024 int x; 1062 int x;
1025 int y; 1063 int y;
1026 } 1064 }
1027 1065
1028 class A { 1066 class A {
1029 final I1 a; 1067 final I1 a;
1030 } 1068 }
1031 1069
1032 class B { 1070 class B {
1033 final I2 a; 1071 final I2 a;
1034 } 1072 }
1035 1073
1036 class C1 extends A implements B { 1074 class C1 extends A implements B {
1037 I3 get a => null; 1075 I3 get a => null;
1038 } 1076 }
1039 1077
1040 class C2 extends A implements B { 1078 class C2 extends A implements B {
1041 /*severe:InvalidMethodOverride*/get a => null; 1079 /*severe:InvalidMethodOverride*/get a => null;
1042 } 1080 }
1043 ''' 1081 '''
1044 }, inferFromOverrides: true); 1082 },
1045 }); 1083 inferFromOverrides: true);
1046 1084
1047 test('infer from RHS only if it wont conflict with overridden fields', () { 1085 testChecker(
1048 testChecker({ 1086 'infer from RHS only if it wont conflict with overridden fields',
1049 '/main.dart': ''' 1087 {
1088 '/main.dart': '''
1050 class A { 1089 class A {
1051 var x; 1090 var x;
1052 } 1091 }
1053 1092
1054 class B extends A { 1093 class B extends A {
1055 var x = 2; 1094 var x = 2;
1056 } 1095 }
1057 1096
1058 foo() { 1097 foo() {
1059 String y = /*info:DynamicCast*/new B().x; 1098 String y = /*info:DynamicCast*/new B().x;
1060 int z = /*info:DynamicCast*/new B().x; 1099 int z = /*info:DynamicCast*/new B().x;
1061 } 1100 }
1062 ''' 1101 '''
1063 }, inferFromOverrides: true); 1102 },
1103 inferFromOverrides: true);
1064 1104
1065 testChecker({ 1105 testChecker(
1066 '/main.dart': ''' 1106 'infer from RHS only if it wont conflict with overridden fields 2',
1107 {
1108 '/main.dart': '''
1067 class A { 1109 class A {
1068 final x; 1110 final x;
1069 } 1111 }
1070 1112
1071 class B extends A { 1113 class B extends A {
1072 final x = 2; 1114 final x = 2;
1073 } 1115 }
1074 1116
1075 foo() { 1117 foo() {
1076 String y = /*severe:StaticTypeError*/new B().x; 1118 String y = /*severe:StaticTypeError*/new B().x;
1077 int z = new B().x; 1119 int z = new B().x;
1078 } 1120 }
1079 ''' 1121 '''
1080 }, inferFromOverrides: true); 1122 },
1081 }); 1123 inferFromOverrides: true);
1082 1124
1083 test('infer correctly on multiple variables declared together', () { 1125 testChecker(
1084 testChecker({ 1126 'infer correctly on multiple variables declared together',
1085 '/main.dart': ''' 1127 {
1128 '/main.dart': '''
1086 class A { 1129 class A {
1087 var x, y = 2, z = "hi"; 1130 var x, y = 2, z = "hi";
1088 } 1131 }
1089 1132
1090 class B extends A { 1133 class B extends A {
1091 var x = 2, y = 3, z, w = 2; 1134 var x = 2, y = 3, z, w = 2;
1092 } 1135 }
1093 1136
1094 foo() { 1137 foo() {
1095 String s; 1138 String s;
1096 int i; 1139 int i;
1097 1140
1098 s = /*info:DynamicCast*/new B().x; 1141 s = /*info:DynamicCast*/new B().x;
1099 s = /*severe:StaticTypeError*/new B().y; 1142 s = /*severe:StaticTypeError*/new B().y;
1100 s = new B().z; 1143 s = new B().z;
1101 s = /*severe:StaticTypeError*/new B().w; 1144 s = /*severe:StaticTypeError*/new B().w;
1102 1145
1103 i = /*info:DynamicCast*/new B().x; 1146 i = /*info:DynamicCast*/new B().x;
1104 i = new B().y; 1147 i = new B().y;
1105 i = /*severe:StaticTypeError*/new B().z; 1148 i = /*severe:StaticTypeError*/new B().z;
1106 i = new B().w; 1149 i = new B().w;
1107 } 1150 }
1108 ''' 1151 '''
1109 }, inferFromOverrides: true); 1152 },
1110 }); 1153 inferFromOverrides: true);
1111 1154
1112 test('infer consts transitively', () { 1155 testChecker(
1113 testChecker({ 1156 'infer consts transitively',
1114 '/b.dart': ''' 1157 {
1158 '/b.dart': '''
1115 const b1 = 2; 1159 const b1 = 2;
1116 ''', 1160 ''',
1117 '/a.dart': ''' 1161 '/a.dart': '''
1118 import 'main.dart'; 1162 import 'main.dart';
1119 import 'b.dart'; 1163 import 'b.dart';
1120 const a1 = m2; 1164 const a1 = m2;
1121 const a2 = b1; 1165 const a2 = b1;
1122 ''', 1166 ''',
1123 '/main.dart': ''' 1167 '/main.dart': '''
1124 import 'a.dart'; 1168 import 'a.dart';
1125 const m1 = a1; 1169 const m1 = a1;
1126 const m2 = a2; 1170 const m2 = a2;
1127 1171
1128 foo() { 1172 foo() {
1129 int i; 1173 int i;
1130 i = m1; 1174 i = m1;
1131 } 1175 }
1132 ''' 1176 '''
1133 }, inferFromOverrides: true, inferTransitively: true); 1177 },
1134 }); 1178 inferFromOverrides: true,
1179 inferTransitively: true);
1135 1180
1136 test('infer statics transitively', () { 1181 testChecker(
1137 testChecker({ 1182 'infer statics transitively',
1138 '/b.dart': ''' 1183 {
1184 '/b.dart': '''
1139 final b1 = 2; 1185 final b1 = 2;
1140 ''', 1186 ''',
1141 '/a.dart': ''' 1187 '/a.dart': '''
1142 import 'main.dart'; 1188 import 'main.dart';
1143 import 'b.dart'; 1189 import 'b.dart';
1144 final a1 = m2; 1190 final a1 = m2;
1145 class A { 1191 class A {
1146 static final a2 = b1; 1192 static final a2 = b1;
1147 } 1193 }
1148 ''', 1194 ''',
1149 '/main.dart': ''' 1195 '/main.dart': '''
1150 import 'a.dart'; 1196 import 'a.dart';
1151 final m1 = a1; 1197 final m1 = a1;
1152 final m2 = A.a2; 1198 final m2 = A.a2;
1153 1199
1154 foo() { 1200 foo() {
1155 int i; 1201 int i;
1156 i = m1; 1202 i = m1;
1157 } 1203 }
1158 ''' 1204 '''
1159 }, inferFromOverrides: true, inferTransitively: true); 1205 },
1206 inferFromOverrides: true,
1207 inferTransitively: true);
1160 1208
1161 testChecker({ 1209 testChecker(
1162 '/main.dart': ''' 1210 'infer statics transitively 2',
1211 {
1212 '/main.dart': '''
1163 const x1 = 1; 1213 const x1 = 1;
1164 final x2 = 1; 1214 final x2 = 1;
1165 final y1 = x1; 1215 final y1 = x1;
1166 final y2 = x2; 1216 final y2 = x2;
1167 1217
1168 foo() { 1218 foo() {
1169 int i; 1219 int i;
1170 i = y1; 1220 i = y1;
1171 i = y2; 1221 i = y2;
1172 } 1222 }
1173 ''' 1223 '''
1174 }, inferFromOverrides: true, inferTransitively: true); 1224 },
1225 inferFromOverrides: true,
1226 inferTransitively: true);
1175 1227
1176 testChecker({ 1228 testChecker(
1177 '/a.dart': ''' 1229 'infer statics transitively 3',
1230 {
1231 '/a.dart': '''
1178 const a1 = 3; 1232 const a1 = 3;
1179 const a2 = 4; 1233 const a2 = 4;
1180 class A { 1234 class A {
1181 a3; 1235 a3;
1182 } 1236 }
1183 ''', 1237 ''',
1184 '/main.dart': ''' 1238 '/main.dart': '''
1185 import 'a.dart' show a1, A; 1239 import 'a.dart' show a1, A;
1186 import 'a.dart' as p show a2, A; 1240 import 'a.dart' as p show a2, A;
1187 const t1 = 1; 1241 const t1 = 1;
1188 const t2 = t1; 1242 const t2 = t1;
1189 const t3 = a1; 1243 const t3 = a1;
1190 const t4 = p.a2; 1244 const t4 = p.a2;
1191 const t5 = A.a3; 1245 const t5 = A.a3;
1192 const t6 = p.A.a3; 1246 const t6 = p.A.a3;
1193 1247
1194 foo() { 1248 foo() {
1195 int i; 1249 int i;
1196 i = t1; 1250 i = t1;
1197 i = t2; 1251 i = t2;
1198 i = t3; 1252 i = t3;
1199 i = t4; 1253 i = t4;
1200 } 1254 }
1201 ''' 1255 '''
1202 }, inferFromOverrides: true, inferTransitively: true); 1256 },
1203 }); 1257 inferFromOverrides: true,
1258 inferTransitively: true);
1204 1259
1205 test('infer statics with method invocations', () { 1260 testChecker(
1206 testChecker({ 1261 'infer statics with method invocations',
1207 '/a.dart': ''' 1262 {
1263 '/a.dart': '''
1208 m3(String a, String b, [a1,a2]) {} 1264 m3(String a, String b, [a1,a2]) {}
1209 ''', 1265 ''',
1210 '/main.dart': ''' 1266 '/main.dart': '''
1211 import 'a.dart'; 1267 import 'a.dart';
1212 class T { 1268 class T {
1213 static final T foo = m1(m2(m3('', ''))); 1269 static final T foo = m1(m2(m3('', '')));
1214 static T m1(String m) { return null; } 1270 static T m1(String m) { return null; }
1215 static String m2(e) { return ''; } 1271 static String m2(e) { return ''; }
1216 } 1272 }
1217 1273
1218 1274
1219 ''' 1275 '''
1220 }, inferFromOverrides: true, inferTransitively: true); 1276 },
1221 }); 1277 inferFromOverrides: true,
1278 inferTransitively: true);
1222 1279
1223 test('downwards inference: miscellaneous', () { 1280 testChecker(
1224 testChecker({ 1281 'downwards inference: miscellaneous',
1225 '/main.dart': ''' 1282 {
1283 '/main.dart': '''
1226 typedef (T x); 1284 typedef (T x);
1227 class A<T> { 1285 class A<T> {
1228 Function2<T> x; 1286 Function2<T> x;
1229 A(this.x); 1287 A(this.x);
1230 } 1288 }
1231 void main() { 1289 void main() {
1232 { // Variables, nested literals 1290 { // Variables, nested literals
1233 var x = "hello"; 1291 var x = "hello";
1234 var y = 3; 1292 var y = 3;
1235 void f(List<Map<int, String>> l) {}; 1293 void f(List<Map<int, String>> l) {};
1236 f(/*info:InferredTypeLiteral*/[{y: x}]); 1294 f(/*info:InferredTypeLiteral*/[{y: x}]);
1237 } 1295 }
1238 { 1296 {
1239 int f(int x) {}; 1297 int f(int x) {};
1240 A<int> a = /*info:InferredTypeAllocation*/new A(f); 1298 A<int> a = /*info:InferredTypeAllocation*/new A(f);
1241 } 1299 }
1242 } 1300 }
1243 ''' 1301 '''
1244 }, inferDownwards: true); 1302 },
1245 }); 1303 inferDownwards: true);
1246 1304
1247 test('downwards inference on instance creations', () { 1305 group('downwards inference on instance creations', () {
1248 String mk(String info) => ''' 1306 String mk(String info) => '''
1249 class A<S, T> { 1307 class A<S, T> {
1250 S x; 1308 S x;
1251 T y; 1309 T y;
1252 A(this.x, this.y); 1310 A(this.x, this.y);
1253 A.named(this.x, this.y); 1311 A.named(this.x, this.y);
1254 } 1312 }
1255 1313
1256 class B<S, T> extends A<T, S> { 1314 class B<S, T> extends A<T, S> {
1257 B(S y, T x) : super(x, y); 1315 B(S y, T x) : super(x, y);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1332 { // Check named and optional arguments 1390 { // Check named and optional arguments
1333 A<int, String> a0 = /*$info*/new F(3, "hello", a: [3], b: ["hello"]); 1391 A<int, String> a0 = /*$info*/new F(3, "hello", a: [3], b: ["hello"]);
1334 A<int, String> a1 = /*severe:StaticTypeError*/new F(3, "hello", a: ["h ello"], b:[3]); 1392 A<int, String> a1 = /*severe:StaticTypeError*/new F(3, "hello", a: ["h ello"], b:[3]);
1335 A<int, String> a2 = /*$info*/new F.named(3, "hello", 3, "hello"); 1393 A<int, String> a2 = /*$info*/new F.named(3, "hello", 3, "hello");
1336 A<int, String> a3 = /*$info*/new F.named(3, "hello"); 1394 A<int, String> a3 = /*$info*/new F.named(3, "hello");
1337 A<int, String> a4 = /*severe:StaticTypeError*/new F.named(3, "hello", "hello", 3); 1395 A<int, String> a4 = /*severe:StaticTypeError*/new F.named(3, "hello", "hello", 3);
1338 A<int, String> a5 = /*severe:StaticTypeError*/new F.named(3, "hello", "hello"); 1396 A<int, String> a5 = /*severe:StaticTypeError*/new F.named(3, "hello", "hello");
1339 } 1397 }
1340 } 1398 }
1341 '''; 1399 ''';
1342 testChecker({'/main.dart': mk("info:InferredTypeAllocation")}, 1400 testChecker(
1401 'infer downwards', {'/main.dart': mk("info:InferredTypeAllocation")},
1343 inferDownwards: true); 1402 inferDownwards: true);
1344 testChecker({'/main.dart': mk("severe:StaticTypeError")}, 1403 testChecker(
1404 'no infer downwards', {'/main.dart': mk("severe:StaticTypeError")},
1345 inferDownwards: false); 1405 inferDownwards: false);
1346 }); 1406 });
1347 1407
1348 test('downwards inference on list literals', () { 1408 group('downwards inference on list literals', () {
1349 String mk(String info) => ''' 1409 String mk(String info) => '''
1350 void foo([List<String> list1 = /*$info*/const [], 1410 void foo([List<String> list1 = /*$info*/const [],
1351 List<String> list2 = /*severe:StaticTypeError*/const [42]]) { 1411 List<String> list2 = /*severe:StaticTypeError*/const [42]]) {
1352 } 1412 }
1353 1413
1354 void main() { 1414 void main() {
1355 { 1415 {
1356 List<int> l0 = /*$info*/[]; 1416 List<int> l0 = /*$info*/[];
1357 List<int> l1 = /*$info*/[3]; 1417 List<int> l1 = /*$info*/[3];
1358 List<int> l2 = /*severe:StaticTypeError*/["hello"]; 1418 List<int> l2 = /*severe:StaticTypeError*/["hello"];
(...skipping 18 matching lines...) Expand all
1377 Iterable<int> i3 = /*severe:StaticTypeError*/["hello", 3]; 1437 Iterable<int> i3 = /*severe:StaticTypeError*/["hello", 3];
1378 } 1438 }
1379 { 1439 {
1380 const List<int> c0 = /*$info*/const []; 1440 const List<int> c0 = /*$info*/const [];
1381 const List<int> c1 = /*$info*/const [3]; 1441 const List<int> c1 = /*$info*/const [3];
1382 const List<int> c2 = /*severe:StaticTypeError*/const ["hello"]; 1442 const List<int> c2 = /*severe:StaticTypeError*/const ["hello"];
1383 const List<int> c3 = /*severe:StaticTypeError*/const ["hello", 3]; 1443 const List<int> c3 = /*severe:StaticTypeError*/const ["hello", 3];
1384 } 1444 }
1385 } 1445 }
1386 '''; 1446 ''';
1387 testChecker({'/main.dart': mk("info:InferredTypeLiteral")}, 1447 testChecker(
1448 'infer downwards', {'/main.dart': mk("info:InferredTypeLiteral")},
1388 inferDownwards: true); 1449 inferDownwards: true);
1389 testChecker({'/main.dart': mk("severe:StaticTypeError")}, 1450 testChecker(
1451 'no infer downwards', {'/main.dart': mk("severe:StaticTypeError")},
1390 inferDownwards: false); 1452 inferDownwards: false);
1391 }); 1453 });
1392 1454
1393 test('downwards inference on function arguments', () { 1455 group('downwards inference on function arguments', () {
1394 String mk(String info) => ''' 1456 String mk(String info) => '''
1395 void f0(List<int> a) {}; 1457 void f0(List<int> a) {};
1396 void f1({List<int> a}) {}; 1458 void f1({List<int> a}) {};
1397 void f2(Iterable<int> a) {}; 1459 void f2(Iterable<int> a) {};
1398 void f3(Iterable<Iterable<int>> a) {}; 1460 void f3(Iterable<Iterable<int>> a) {};
1399 void f4({Iterable<Iterable<int>> a}) {}; 1461 void f4({Iterable<Iterable<int>> a}) {};
1400 void main() { 1462 void main() {
1401 f0(/*$info*/[]); 1463 f0(/*$info*/[]);
1402 f0(/*$info*/[3]); 1464 f0(/*$info*/[3]);
1403 f0(/*severe:StaticTypeError*/["hello"]); 1465 f0(/*severe:StaticTypeError*/["hello"]);
(...skipping 13 matching lines...) Expand all
1417 f3(/*$info*/[[3]]); 1479 f3(/*$info*/[[3]]);
1418 f3(/*severe:StaticTypeError*/[["hello"]]); 1480 f3(/*severe:StaticTypeError*/[["hello"]]);
1419 f3(/*severe:StaticTypeError*/[["hello"], [3]]); 1481 f3(/*severe:StaticTypeError*/[["hello"], [3]]);
1420 1482
1421 f4(a: /*$info*/[]); 1483 f4(a: /*$info*/[]);
1422 f4(a: /*$info*/[[3]]); 1484 f4(a: /*$info*/[[3]]);
1423 f4(a: /*severe:StaticTypeError*/[["hello"]]); 1485 f4(a: /*severe:StaticTypeError*/[["hello"]]);
1424 f4(a: /*severe:StaticTypeError*/[["hello"], [3]]); 1486 f4(a: /*severe:StaticTypeError*/[["hello"], [3]]);
1425 } 1487 }
1426 '''; 1488 ''';
1427 testChecker({'/main.dart': mk("info:InferredTypeLiteral")}, 1489 testChecker(
1490 'infer downwards', {'/main.dart': mk("info:InferredTypeLiteral")},
1428 inferDownwards: true); 1491 inferDownwards: true);
1429 testChecker({'/main.dart': mk("severe:StaticTypeError")}, 1492 testChecker(
1493 'no infer downwards', {'/main.dart': mk("severe:StaticTypeError")},
1430 inferDownwards: false); 1494 inferDownwards: false);
1431 }); 1495 });
1432 1496
1433 test('downwards inference on map literals', () { 1497 group('downwards inference on map literals', () {
1434 String mk(String info) => ''' 1498 String mk(String info) => '''
1435 void foo([Map<int, String> m1 = /*$info*/const {1: "hello"}, 1499 void foo([Map<int, String> m1 = /*$info*/const {1: "hello"},
1436 Map<int, String> m1 = /*severe:StaticTypeError*/const {"hello": "world"}]) { 1500 Map<int, String> m1 = /*severe:StaticTypeError*/const {"hello": "world"}]) {
1437 } 1501 }
1438 void main() { 1502 void main() {
1439 { 1503 {
1440 Map<int, String> l0 = /*$info*/{}; 1504 Map<int, String> l0 = /*$info*/{};
1441 Map<int, String> l1 = /*$info*/{3: "hello"}; 1505 Map<int, String> l1 = /*$info*/{3: "hello"};
1442 Map<int, String> l2 = /*severe:StaticTypeError*/{"hello": "hello"}; 1506 Map<int, String> l2 = /*severe:StaticTypeError*/{"hello": "hello"};
1443 Map<int, String> l3 = /*severe:StaticTypeError*/{3: 3}; 1507 Map<int, String> l3 = /*severe:StaticTypeError*/{3: 3};
(...skipping 27 matching lines...) Expand all
1471 } 1535 }
1472 { 1536 {
1473 const Map<int, String> l0 = /*$info*/const {}; 1537 const Map<int, String> l0 = /*$info*/const {};
1474 const Map<int, String> l1 = /*$info*/const {3: "hello"}; 1538 const Map<int, String> l1 = /*$info*/const {3: "hello"};
1475 const Map<int, String> l2 = /*severe:StaticTypeError*/const {"hello": "hello"}; 1539 const Map<int, String> l2 = /*severe:StaticTypeError*/const {"hello": "hello"};
1476 const Map<int, String> l3 = /*severe:StaticTypeError*/const {3: 3}; 1540 const Map<int, String> l3 = /*severe:StaticTypeError*/const {3: 3};
1477 const Map<int, String> l4 = /*severe:StaticTypeError*/const {3:"hello" , "hello": 3}; 1541 const Map<int, String> l4 = /*severe:StaticTypeError*/const {3:"hello" , "hello": 3};
1478 } 1542 }
1479 } 1543 }
1480 '''; 1544 ''';
1481 testChecker({'/main.dart': mk("info:InferredTypeLiteral")}, 1545 testChecker(
1546 'infer downwards', {'/main.dart': mk("info:InferredTypeLiteral")},
1482 inferDownwards: true); 1547 inferDownwards: true);
1483 testChecker({'/main.dart': mk("severe:StaticTypeError")}, 1548 testChecker(
1549 'no infer downwards', {'/main.dart': mk("severe:StaticTypeError")},
1484 inferDownwards: false); 1550 inferDownwards: false);
1485 }); 1551 });
1486 1552
1487 test('downwards inference on function expressions', () { 1553 testChecker(
1488 testChecker({ 1554 'downwards inference on function expressions',
1489 '/main.dart': ''' 1555 {
1556 '/main.dart': '''
1490 typedef T Function2<S, T>(S x); 1557 typedef T Function2<S, T>(S x);
1491 1558
1492 void main () { 1559 void main () {
1493 { 1560 {
1494 Function2<int, String> l0 = (int x) => null; 1561 Function2<int, String> l0 = (int x) => null;
1495 Function2<int, String> l1 = (int x) => "hello"; 1562 Function2<int, String> l1 = (int x) => "hello";
1496 Function2<int, String> l2 = /*severe:StaticTypeError*/(String x) => "h ello"; 1563 Function2<int, String> l2 = /*severe:StaticTypeError*/(String x) => "h ello";
1497 Function2<int, String> l3 = /*severe:StaticTypeError*/(int x) => 3; 1564 Function2<int, String> l3 = /*severe:StaticTypeError*/(int x) => 3;
1498 Function2<int, String> l4 = /*warning:UninferredClosure should be seve re:StaticTypeError*/(int x) {return 3}; 1565 Function2<int, String> l4 = /*warning:UninferredClosure should be seve re:StaticTypeError*/(int x) {return 3};
1499 } 1566 }
(...skipping 12 matching lines...) Expand all
1512 } 1579 }
1513 { 1580 {
1514 Function2<int, int> l0 = /*info:InferredTypeClosure*/(x) => x; 1581 Function2<int, int> l0 = /*info:InferredTypeClosure*/(x) => x;
1515 Function2<int, int> l1 = /*info:InferredTypeClosure*/(x) => /*info:Dyn amicInvoke should be pass*/x+1; 1582 Function2<int, int> l1 = /*info:InferredTypeClosure*/(x) => /*info:Dyn amicInvoke should be pass*/x+1;
1516 Function2<int, String> l2 = /*info:InferredTypeClosure should be sever e:StaticTypeError*/(x) => x; 1583 Function2<int, String> l2 = /*info:InferredTypeClosure should be sever e:StaticTypeError*/(x) => x;
1517 Function2<int, String> l3 = /*info:InferredTypeClosure should be sever e:StaticTypeError*/(x) => /*info:DynamicInvoke should be pass*/x.substring(3); 1584 Function2<int, String> l3 = /*info:InferredTypeClosure should be sever e:StaticTypeError*/(x) => /*info:DynamicInvoke should be pass*/x.substring(3);
1518 Function2<String, String> l4 = /*info:InferredTypeClosure*/(x) => /*in fo:DynamicInvoke should be pass*/x.substring(3); 1585 Function2<String, String> l4 = /*info:InferredTypeClosure*/(x) => /*in fo:DynamicInvoke should be pass*/x.substring(3);
1519 } 1586 }
1520 } 1587 }
1521 ''' 1588 '''
1522 }, inferDownwards: true); 1589 },
1523 }); 1590 inferDownwards: true);
1524 1591
1525 test( 1592 testChecker('inferred initializing formal checks default value', {
1526 'inferred initializing formal checks default value', 1593 '/main.dart': '''
1527 () => testChecker({
1528 '/main.dart': '''
1529 class Foo { 1594 class Foo {
1530 var x = 1; 1595 var x = 1;
1531 Foo([this.x = /*severe:StaticTypeError*/"1"]); 1596 Foo([this.x = /*severe:StaticTypeError*/"1"]);
1532 }''' 1597 }'''
1533 })); 1598 });
1534 } 1599 }
OLDNEW
« no previous file with comments | « test/checker/checker_test.dart ('k') | test/testing.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698