OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 import 'dart:async'; |
5 import "package:expect/expect.dart"; | 6 import "package:expect/expect.dart"; |
6 import '../../../sdk/lib/_internal/compiler/implementation/scanner/scannerlib.da
rt'; | 7 import '../../../sdk/lib/_internal/compiler/implementation/scanner/scannerlib.da
rt'; |
7 import '../../../sdk/lib/_internal/compiler/implementation/source_file.dart'; | 8 import '../../../sdk/lib/_internal/compiler/implementation/source_file.dart'; |
8 import '../../../sdk/lib/_internal/compiler/implementation/types/types.dart'; | 9 import '../../../sdk/lib/_internal/compiler/implementation/types/types.dart'; |
9 | 10 |
10 import "parser_helper.dart"; | 11 import "parser_helper.dart"; |
11 import "compiler_helper.dart"; | 12 import "compiler_helper.dart"; |
12 | 13 |
13 /** | 14 /** |
14 * Finds the node corresponding to the last occurence of the substring | 15 * Finds the node corresponding to the last occurence of the substring |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 */ | 135 */ |
135 void checkFieldHasUknownType(String className, String fieldName) { | 136 void checkFieldHasUknownType(String className, String fieldName) { |
136 return Expect.isTrue( | 137 return Expect.isTrue( |
137 inferrer.inferredFieldTypes[findField(className, fieldName)] | 138 inferrer.inferredFieldTypes[findField(className, fieldName)] |
138 .isUnknown()); | 139 .isUnknown()); |
139 } | 140 } |
140 } | 141 } |
141 | 142 |
142 const String CORELIB = r''' | 143 const String CORELIB = r''' |
143 print(var obj) {} | 144 print(var obj) {} |
144 abstract class num { | 145 abstract class num { |
145 num operator +(num x); | 146 num operator +(num x); |
146 num operator *(num x); | 147 num operator *(num x); |
147 num operator -(num x); | 148 num operator -(num x); |
148 operator ==(x); | 149 operator ==(x); |
149 num floor(); | 150 num floor(); |
150 } | 151 } |
151 abstract class int extends num { | 152 abstract class int extends num { |
152 bool get isEven; | 153 bool get isEven; |
153 } | 154 } |
154 abstract class double extends num { | 155 abstract class double extends num { |
155 bool get isNaN; | 156 bool get isNaN; |
156 } | 157 } |
157 class bool {} | 158 class bool {} |
158 class String {} | 159 class String {} |
159 class Object {} | 160 class Object {} |
160 class Function {} | 161 class Function {} |
161 abstract class List<E> { | 162 abstract class List<E> { |
162 factory List([int length]) { | 163 factory List([int length]) { |
163 return JS('JSExtendableArray', r'new Array(#)', length); | 164 return JS('JSExtendableArray', r'new Array(#)', length); |
164 } | 165 } |
165 } | 166 } |
166 abstract class Map<K, V> {} | 167 abstract class Map<K, V> {} |
167 class Closure {} | 168 class Closure {} |
168 class Null {} | 169 class Null {} |
169 class Type {} | 170 class Type {} |
170 class StackTrace {} | 171 class StackTrace {} |
171 class Dynamic_ {} | 172 class Dynamic_ {} |
172 bool identical(Object a, Object b) {}'''; | 173 bool identical(Object a, Object b) {}'''; |
173 | 174 |
174 AnalysisResult analyze(String code, {int maxConcreteTypeSize: 1000}) { | 175 Future<AnalysisResult> analyze(String code, {int maxConcreteTypeSize: 1000}) { |
175 Uri uri = new Uri(scheme: 'source'); | 176 Uri uri = new Uri(scheme: 'source'); |
176 MockCompiler compiler = new MockCompiler( | 177 MockCompiler compiler = new MockCompiler( |
177 coreSource: CORELIB, | 178 coreSource: CORELIB, |
178 enableConcreteTypeInference: true, | 179 enableConcreteTypeInference: true, |
179 maxConcreteTypeSize: maxConcreteTypeSize); | 180 maxConcreteTypeSize: maxConcreteTypeSize); |
180 compiler.sourceFiles[uri.toString()] = new SourceFile(uri.toString(), code); | 181 compiler.sourceFiles[uri.toString()] = new SourceFile(uri.toString(), code); |
181 compiler.typesTask.concreteTypesInferrer.testMode = true; | 182 compiler.typesTask.concreteTypesInferrer.testMode = true; |
182 compiler.runCompiler(uri); | 183 return compiler.runCompiler(uri).then((_) { |
183 return new AnalysisResult(compiler); | 184 return new AnalysisResult(compiler); |
| 185 }); |
184 } | 186 } |
185 | 187 |
186 testDynamicBackDoor() { | 188 testDynamicBackDoor() { |
187 final String source = r""" | 189 final String source = r""" |
188 main () { | 190 main () { |
189 var x = "__dynamic_for_test"; | 191 var x = "__dynamic_for_test"; |
190 x; | 192 x; |
191 } | 193 } |
192 """; | 194 """; |
193 AnalysisResult result = analyze(source); | 195 analyze(source).then((result) { |
194 result.checkNodeHasUnknownType('x'); | 196 result.checkNodeHasUnknownType('x'); |
| 197 }); |
195 } | 198 } |
196 | 199 |
197 testVariableDeclaration() { | 200 testVariableDeclaration() { |
198 final String source = r""" | 201 final String source = r""" |
199 main() { | 202 main() { |
200 var v1; | 203 var v1; |
201 var v2; | 204 var v2; |
202 v2 = 1; | 205 v2 = 1; |
203 v1; v2; | 206 v1; v2; |
204 } | 207 } |
205 """; | 208 """; |
206 AnalysisResult result = analyze(source); | 209 analyze(source).then((result) { |
207 result.checkNodeHasType('v1', [result.nullType]); | 210 result.checkNodeHasType('v1', [result.nullType]); |
208 result.checkNodeHasType('v2', [result.int]); | 211 result.checkNodeHasType('v2', [result.int]); |
| 212 }); |
209 } | 213 } |
210 | 214 |
211 testLiterals() { | 215 testLiterals() { |
212 final String source = r""" | 216 final String source = r""" |
213 main() { | 217 main() { |
214 var v1 = 42; | 218 var v1 = 42; |
215 var v2 = 42.0; | 219 var v2 = 42.0; |
216 var v3 = 'abc'; | 220 var v3 = 'abc'; |
217 var v4 = true; | 221 var v4 = true; |
218 var v5 = null; | 222 var v5 = null; |
219 v1; v2; v3; v4; v5; | 223 v1; v2; v3; v4; v5; |
220 } | 224 } |
221 """; | 225 """; |
222 AnalysisResult result = analyze(source); | 226 analyze(source).then((result) { |
223 result.checkNodeHasType('v1', [result.int]); | 227 result.checkNodeHasType('v1', [result.int]); |
224 result.checkNodeHasType('v2', [result.double]); | 228 result.checkNodeHasType('v2', [result.double]); |
225 result.checkNodeHasType('v3', [result.string]); | 229 result.checkNodeHasType('v3', [result.string]); |
226 result.checkNodeHasType('v4', [result.bool]); | 230 result.checkNodeHasType('v4', [result.bool]); |
227 result.checkNodeHasType('v5', [result.nullType]); | 231 result.checkNodeHasType('v5', [result.nullType]); |
| 232 }); |
228 } | 233 } |
229 | 234 |
230 testRedefinition() { | 235 testRedefinition() { |
231 final String source = r""" | 236 final String source = r""" |
232 main() { | 237 main() { |
233 var foo = 42; | 238 var foo = 42; |
234 foo = 'abc'; | 239 foo = 'abc'; |
235 foo; | 240 foo; |
236 } | 241 } |
237 """; | 242 """; |
238 AnalysisResult result = analyze(source); | 243 analyze(source).then((result) { |
239 result.checkNodeHasType('foo', [result.string]); | 244 result.checkNodeHasType('foo', [result.string]); |
| 245 }); |
240 } | 246 } |
241 | 247 |
242 testIfThenElse() { | 248 testIfThenElse() { |
243 final String source = r""" | 249 final String source = r""" |
244 main() { | 250 main() { |
245 var foo = 42; | 251 var foo = 42; |
246 if (true) { | 252 if (true) { |
247 foo = 'abc'; | 253 foo = 'abc'; |
248 } else { | 254 } else { |
249 foo = false; | 255 foo = false; |
250 } | 256 } |
251 foo; | 257 foo; |
252 } | 258 } |
253 """; | 259 """; |
254 AnalysisResult result = analyze(source); | 260 analyze(source).then((result) { |
255 result.checkNodeHasType('foo', [result.string, result.bool]); | 261 result.checkNodeHasType('foo', [result.string, result.bool]); |
| 262 }); |
256 } | 263 } |
257 | 264 |
258 testTernaryIf() { | 265 testTernaryIf() { |
259 final String source = r""" | 266 final String source = r""" |
260 main() { | 267 main() { |
261 var foo = 42; | 268 var foo = 42; |
262 foo = true ? 'abc' : false; | 269 foo = true ? 'abc' : false; |
263 foo; | 270 foo; |
264 } | 271 } |
265 """; | 272 """; |
266 AnalysisResult result = analyze(source); | 273 analyze(source).then((result) { |
267 result.checkNodeHasType('foo', [result.string, result.bool]); | 274 result.checkNodeHasType('foo', [result.string, result.bool]); |
| 275 }); |
268 } | 276 } |
269 | 277 |
270 testWhile() { | 278 testWhile() { |
271 final String source = r""" | 279 final String source = r""" |
272 class A { f() => new B(); } | 280 class A { f() => new B(); } |
273 class B { f() => new C(); } | 281 class B { f() => new C(); } |
274 class C { f() => new A(); } | 282 class C { f() => new A(); } |
275 main() { | 283 main() { |
276 var bar = null; | 284 var bar = null; |
277 var foo = new A(); | 285 var foo = new A(); |
278 while(bar = 42) { | 286 while(bar = 42) { |
279 foo = foo.f(); | 287 foo = foo.f(); |
280 } | 288 } |
281 foo; bar; | 289 foo; bar; |
282 } | 290 } |
283 """; | 291 """; |
284 AnalysisResult result = analyze(source); | 292 analyze(source).then((result) { |
285 result.checkNodeHasType( | 293 result.checkNodeHasType( |
286 'foo', | 294 'foo', |
287 [result.base('A'), result.base('B'), result.base('C')]); | 295 [result.base('A'), result.base('B'), result.base('C')]); |
288 // Check that the condition is evaluated. | 296 // Check that the condition is evaluated. |
289 result.checkNodeHasType('bar', [result.int]); | 297 result.checkNodeHasType('bar', [result.int]); |
| 298 }); |
290 } | 299 } |
291 | 300 |
292 testFor1() { | 301 testFor1() { |
293 final String source = r""" | 302 final String source = r""" |
294 class A { f() => new B(); } | 303 class A { f() => new B(); } |
295 class B { f() => new C(); } | 304 class B { f() => new C(); } |
296 class C { f() => new A(); } | 305 class C { f() => new A(); } |
297 main() { | 306 main() { |
298 var foo = new A(); | 307 var foo = new A(); |
299 for(;;) { | 308 for(;;) { |
300 foo = foo.f(); | 309 foo = foo.f(); |
301 } | 310 } |
302 foo; | 311 foo; |
303 } | 312 } |
304 """; | 313 """; |
305 AnalysisResult result = analyze(source); | 314 analyze(source).then((result) { |
306 result.checkNodeHasType( | 315 result.checkNodeHasType( |
307 'foo', | 316 'foo', |
308 [result.base('A'), result.base('B'), result.base('C')]); | 317 [result.base('A'), result.base('B'), result.base('C')]); |
| 318 }); |
309 } | 319 } |
310 | 320 |
311 testFor2() { | 321 testFor2() { |
312 final String source = r""" | 322 final String source = r""" |
313 class A { f() => new B(); test() => true; } | 323 class A { f() => new B(); test() => true; } |
314 class B { f() => new A(); test() => true; } | 324 class B { f() => new A(); test() => true; } |
315 main() { | 325 main() { |
316 var bar = null; | 326 var bar = null; |
317 var foo = new A(); | 327 var foo = new A(); |
318 for(var i = new A(); bar = 42; i = i.f()) { | 328 for(var i = new A(); bar = 42; i = i.f()) { |
319 foo = i; | 329 foo = i; |
320 } | 330 } |
321 foo; bar; | 331 foo; bar; |
322 } | 332 } |
323 """; | 333 """; |
324 AnalysisResult result = analyze(source); | 334 analyze(source).then((result) { |
325 result.checkNodeHasType('foo', [result.base('A'), result.base('B')]); | 335 result.checkNodeHasType('foo', [result.base('A'), result.base('B')]); |
326 // Check that the condition is evaluated. | 336 // Check that the condition is evaluated. |
327 result.checkNodeHasType('bar', [result.int]); | 337 result.checkNodeHasType('bar', [result.int]); |
| 338 }); |
328 } | 339 } |
329 | 340 |
330 testFor3() { | 341 testFor3() { |
331 final String source = r""" | 342 final String source = r""" |
332 main() { | 343 main() { |
333 var i = 1; | 344 var i = 1; |
334 for(;;) { | 345 for(;;) { |
335 var x = 2; | 346 var x = 2; |
336 i = x; | 347 i = x; |
337 } | 348 } |
338 i; | 349 i; |
339 } | 350 } |
340 """; | 351 """; |
341 AnalysisResult result = analyze(source); | 352 analyze(source).then((result) { |
342 result.checkNodeHasType('i', [result.int]); | 353 result.checkNodeHasType('i', [result.int]); |
| 354 }); |
343 } | 355 } |
344 | 356 |
345 testToplevelVariable() { | 357 testToplevelVariable() { |
346 final String source = r""" | 358 final String source = r""" |
347 final top = 'abc'; | 359 final top = 'abc'; |
348 class A { | 360 class A { |
349 f() => top; | 361 f() => top; |
350 } | 362 } |
351 main() { | 363 main() { |
352 var foo = top; | 364 var foo = top; |
353 var bar = new A().f(); | 365 var bar = new A().f(); |
354 foo; bar; | 366 foo; bar; |
355 } | 367 } |
356 """; | 368 """; |
357 AnalysisResult result = analyze(source); | 369 analyze(source).then((result) { |
358 result.checkNodeHasType('foo', [result.string]); | 370 result.checkNodeHasType('foo', [result.string]); |
359 result.checkNodeHasType('bar', [result.string]); | 371 result.checkNodeHasType('bar', [result.string]); |
| 372 }); |
360 } | 373 } |
361 | 374 |
362 testNonRecusiveFunction() { | 375 testNonRecusiveFunction() { |
363 final String source = r""" | 376 final String source = r""" |
364 f(x, y) => true ? x : y; | 377 f(x, y) => true ? x : y; |
365 main() { var foo = f(42, "abc"); foo; } | 378 main() { var foo = f(42, "abc"); foo; } |
366 """; | 379 """; |
367 AnalysisResult result = analyze(source); | 380 analyze(source).then((result) { |
368 result.checkNodeHasType('foo', [result.int, result.string]); | 381 result.checkNodeHasType('foo', [result.int, result.string]); |
| 382 }); |
369 } | 383 } |
370 | 384 |
371 testRecusiveFunction() { | 385 testRecusiveFunction() { |
372 final String source = r""" | 386 final String source = r""" |
373 f(x) { | 387 f(x) { |
374 if (true) return x; | 388 if (true) return x; |
375 else return f(true ? x : "abc"); | 389 else return f(true ? x : "abc"); |
376 } | 390 } |
377 main() { var foo = f(42); foo; } | 391 main() { var foo = f(42); foo; } |
378 """; | 392 """; |
379 AnalysisResult result = analyze(source); | 393 analyze(source).then((result) { |
380 result.checkNodeHasType('foo', [result.int, result.string]); | 394 result.checkNodeHasType('foo', [result.int, result.string]); |
| 395 }); |
381 } | 396 } |
382 | 397 |
383 testMutuallyRecusiveFunction() { | 398 testMutuallyRecusiveFunction() { |
384 final String source = r""" | 399 final String source = r""" |
385 f() => true ? 42 : g(); | 400 f() => true ? 42 : g(); |
386 g() => true ? "abc" : f(); | 401 g() => true ? "abc" : f(); |
387 main() { var foo = f(); foo; } | 402 main() { var foo = f(); foo; } |
388 """; | 403 """; |
389 AnalysisResult result = analyze(source); | 404 analyze(source).then((result) { |
390 result.checkNodeHasType('foo', [result.int, result.string]); | 405 result.checkNodeHasType('foo', [result.int, result.string]); |
| 406 }); |
391 } | 407 } |
392 | 408 |
393 testSimpleSend() { | 409 testSimpleSend() { |
394 final String source = r""" | 410 final String source = r""" |
395 class A { | 411 class A { |
396 f(x) => x; | 412 f(x) => x; |
397 } | 413 } |
398 class B { | 414 class B { |
399 f(x) => 'abc'; | 415 f(x) => 'abc'; |
400 } | 416 } |
401 class C { | 417 class C { |
402 f(x) => 3.14; | 418 f(x) => 3.14; |
403 } | 419 } |
404 class D { | 420 class D { |
405 var f; // we check that this field is ignored in calls to dynamic.f() | 421 var f; // we check that this field is ignored in calls to dynamic.f() |
406 D(this.f); | 422 D(this.f); |
407 } | 423 } |
408 main() { | 424 main() { |
409 new B(); new D(42); // we instantiate B and D but not C | 425 new B(); new D(42); // we instantiate B and D but not C |
410 var foo = new A().f(42); | 426 var foo = new A().f(42); |
411 var bar = "__dynamic_for_test".f(42); | 427 var bar = "__dynamic_for_test".f(42); |
412 foo; bar; | 428 foo; bar; |
413 } | 429 } |
414 """; | 430 """; |
415 AnalysisResult result = analyze(source); | 431 analyze(source).then((result) { |
416 result.checkNodeHasType('foo', [result.int]); | 432 result.checkNodeHasType('foo', [result.int]); |
417 result.checkNodeHasType('bar', [result.int, result.string]); | 433 result.checkNodeHasType('bar', [result.int, result.string]); |
| 434 }); |
418 } | 435 } |
419 | 436 |
420 testSendToClosureField() { | 437 testSendToClosureField() { |
421 final String source = r""" | 438 final String source = r""" |
422 f(x) => x; | 439 f(x) => x; |
423 class A { | 440 class A { |
424 var g; | 441 var g; |
425 A(this.g); | 442 A(this.g); |
426 } | 443 } |
427 main() { | 444 main() { |
428 var foo = new A(f).g(42); | 445 var foo = new A(f).g(42); |
429 foo; | 446 foo; |
430 } | 447 } |
431 """; | 448 """; |
432 AnalysisResult result = analyze(source); | 449 analyze(source).then((result) { |
433 result.checkNodeHasType('foo', [result.int]); | 450 result.checkNodeHasType('foo', [result.int]); |
| 451 }); |
434 } | 452 } |
435 | 453 |
436 testSendToThis1() { | 454 testSendToThis1() { |
437 final String source = r""" | 455 final String source = r""" |
438 class A { | 456 class A { |
439 A(); | 457 A(); |
440 f() => g(); | 458 f() => g(); |
441 g() => 42; | 459 g() => 42; |
442 } | 460 } |
443 main() { | 461 main() { |
444 var foo = new A().f(); | 462 var foo = new A().f(); |
445 foo; | 463 foo; |
446 } | 464 } |
447 """; | 465 """; |
448 AnalysisResult result = analyze(source); | 466 analyze(source).then((result) { |
449 result.checkNodeHasType('foo', [result.int]); | 467 result.checkNodeHasType('foo', [result.int]); |
| 468 }); |
450 } | 469 } |
451 | 470 |
452 testSendToThis2() { | 471 testSendToThis2() { |
453 final String source = r""" | 472 final String source = r""" |
454 class A { | 473 class A { |
455 foo() => this; | 474 foo() => this; |
456 } | 475 } |
457 class B extends A { | 476 class B extends A { |
458 bar() => foo(); | 477 bar() => foo(); |
459 } | 478 } |
460 main() { | 479 main() { |
461 var x = new B().bar(); | 480 var x = new B().bar(); |
462 x; | 481 x; |
463 } | 482 } |
464 """; | 483 """; |
465 AnalysisResult result = analyze(source); | 484 analyze(source).then((result) { |
466 result.checkNodeHasType('x', [result.base('B')]); | 485 result.checkNodeHasType('x', [result.base('B')]); |
| 486 }); |
467 } | 487 } |
468 | 488 |
469 testConstructor() { | 489 testConstructor() { |
470 final String source = r""" | 490 final String source = r""" |
471 class A { | 491 class A { |
472 var x, y, z; | 492 var x, y, z; |
473 A(this.x, a) : y = a { z = 'abc'; } | 493 A(this.x, a) : y = a { z = 'abc'; } |
474 } | 494 } |
475 main() { | 495 main() { |
476 new A(42, 'abc'); | 496 new A(42, 'abc'); |
477 new A(true, null); | 497 new A(true, null); |
478 } | 498 } |
479 """; | 499 """; |
480 AnalysisResult result = analyze(source); | 500 analyze(source).then((result) { |
481 result.checkFieldHasType('A', 'x', [result.int, result.bool]); | 501 result.checkFieldHasType('A', 'x', [result.int, result.bool]); |
482 result.checkFieldHasType('A', 'y', [result.string, result.nullType]); | 502 result.checkFieldHasType('A', 'y', [result.string, result.nullType]); |
483 // TODO(polux): we can be smarter and infer {string} for z | 503 // TODO(polux): we can be smarter and infer {string} for z |
484 result.checkFieldHasType('A', 'z', [result.string, result.nullType]); | 504 result.checkFieldHasType('A', 'z', [result.string, result.nullType]); |
| 505 }); |
485 } | 506 } |
486 | 507 |
487 testGetters() { | 508 testGetters() { |
488 final String source = r""" | 509 final String source = r""" |
489 class A { | 510 class A { |
490 var x; | 511 var x; |
491 A(this.x); | 512 A(this.x); |
492 get y => x; | 513 get y => x; |
493 get z => y; | 514 get z => y; |
494 } | 515 } |
495 class B { | 516 class B { |
496 var x; | 517 var x; |
497 B(this.x); | 518 B(this.x); |
498 } | 519 } |
499 main() { | 520 main() { |
500 var a = new A(42); | 521 var a = new A(42); |
501 var b = new B('abc'); | 522 var b = new B('abc'); |
502 var foo = a.x; | 523 var foo = a.x; |
503 var bar = a.y; | 524 var bar = a.y; |
504 var baz = a.z; | 525 var baz = a.z; |
505 var qux = null.x; | 526 var qux = null.x; |
506 var quux = "__dynamic_for_test".x; | 527 var quux = "__dynamic_for_test".x; |
507 foo; bar; baz; qux; quux; | 528 foo; bar; baz; qux; quux; |
508 } | 529 } |
509 """; | 530 """; |
510 AnalysisResult result = analyze(source); | 531 analyze(source).then((result) { |
511 result.checkNodeHasType('foo', [result.int]); | 532 result.checkNodeHasType('foo', [result.int]); |
512 result.checkNodeHasType('bar', [result.int]); | 533 result.checkNodeHasType('bar', [result.int]); |
513 result.checkNodeHasType('baz', [result.int]); | 534 result.checkNodeHasType('baz', [result.int]); |
514 result.checkNodeHasType('qux', []); | 535 result.checkNodeHasType('qux', []); |
515 result.checkNodeHasType('quux', [result.int, result.string]); | 536 result.checkNodeHasType('quux', [result.int, result.string]); |
| 537 }); |
516 } | 538 } |
517 | 539 |
518 testSetters() { | 540 testSetters() { |
519 final String source = r""" | 541 final String source = r""" |
520 class A { | 542 class A { |
521 var x; | 543 var x; |
522 var w; | 544 var w; |
523 A(this.x, this.w); | 545 A(this.x, this.w); |
524 set y(a) { x = a; z = a; } | 546 set y(a) { x = a; z = a; } |
525 set z(a) { w = a; } | 547 set z(a) { w = a; } |
526 } | 548 } |
527 class B { | 549 class B { |
528 var x; | 550 var x; |
529 B(this.x); | 551 B(this.x); |
530 } | 552 } |
531 main() { | 553 main() { |
532 var a = new A(42, 42); | 554 var a = new A(42, 42); |
533 var b = new B(42); | 555 var b = new B(42); |
534 a.x = 'abc'; | 556 a.x = 'abc'; |
535 a.y = true; | 557 a.y = true; |
536 null.x = 42; // should be ignored | 558 null.x = 42; // should be ignored |
537 "__dynamic_for_test".x = null; | 559 "__dynamic_for_test".x = null; |
538 "__dynamic_for_test".y = 3.14; | 560 "__dynamic_for_test".y = 3.14; |
539 } | 561 } |
540 """; | 562 """; |
541 AnalysisResult result = analyze(source); | 563 analyze(source).then((result) { |
542 result.checkFieldHasType('B', 'x', | 564 result.checkFieldHasType('B', 'x', |
543 [result.int, // new B(42) | 565 [result.int, // new B(42) |
544 result.nullType]); // dynamic.x = null | 566 result.nullType]); // dynamic.x = null |
545 result.checkFieldHasType('A', 'x', | 567 result.checkFieldHasType('A', 'x', |
546 [result.int, // new A(42, ...) | 568 [result.int, // new A(42, ...) |
547 result.string, // a.x = 'abc' | 569 result.string, // a.x = 'abc' |
548 result.bool, // a.y = true | 570 result.bool, // a.y = true |
549 result.nullType, // dynamic.x = null | 571 result.nullType, // dynamic.x = null |
550 result.double]); // dynamic.y = 3.14 | 572 result.double]); // dynamic.y = 3.14 |
551 result.checkFieldHasType('A', 'w', | 573 result.checkFieldHasType('A', 'w', |
552 [result.int, // new A(..., 42) | 574 [result.int, // new A(..., 42) |
553 result.bool, // a.y = true | 575 result.bool, // a.y = true |
554 result.double]); // dynamic.y = double | 576 result.double]); // dynamic.y = double |
| 577 }); |
555 } | 578 } |
556 | 579 |
557 testOptionalNamedParameters() { | 580 testOptionalNamedParameters() { |
558 final String source = r""" | 581 final String source = r""" |
559 class A { | 582 class A { |
560 var x, y, z, w; | 583 var x, y, z, w; |
561 A(this.x, {this.y, this.z, this.w}); | 584 A(this.x, {this.y, this.z, this.w}); |
562 } | 585 } |
563 class B { | 586 class B { |
564 var x, y; | 587 var x, y; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
609 new B(1, 2); // too many positional arguments | 632 new B(1, 2); // too many positional arguments |
610 test.f2('abc', y: true); | 633 test.f2('abc', y: true); |
611 test.f2(1, 2); // too many positional arguments | 634 test.f2(1, 2); // too many positional arguments |
612 | 635 |
613 new C('abc', y: true); | 636 new C('abc', y: true); |
614 new C(1, z: 2); // non-existing named parameter | 637 new C(1, z: 2); // non-existing named parameter |
615 test.f3('abc', y: true); | 638 test.f3('abc', y: true); |
616 test.f3(1, z: 2); // non-existing named parameter | 639 test.f3(1, z: 2); // non-existing named parameter |
617 } | 640 } |
618 """; | 641 """; |
619 AnalysisResult result = analyze(source); | 642 analyze(source).then((result) { |
620 | 643 |
621 final foo = result.base('Foo'); | 644 final foo = result.base('Foo'); |
622 final nil = result.nullType; | 645 final nil = result.nullType; |
623 | 646 |
624 result.checkFieldHasType('A', 'x', [result.int, result.string]); | 647 result.checkFieldHasType('A', 'x', [result.int, result.string]); |
625 result.checkFieldHasType('A', 'y', [nil]); | 648 result.checkFieldHasType('A', 'y', [nil]); |
626 result.checkFieldHasType('A', 'z', [nil, result.double]); | 649 result.checkFieldHasType('A', 'z', [nil, result.double]); |
627 result.checkFieldHasType('A', 'w', [nil, result.bool]); | 650 result.checkFieldHasType('A', 'w', [nil, result.bool]); |
628 result.checkFieldHasType('Test', 'a', [foo, result.int, result.string]); | 651 result.checkFieldHasType('Test', 'a', [foo, result.int, result.string]); |
629 result.checkFieldHasType('Test', 'b', [foo, nil]); | 652 result.checkFieldHasType('Test', 'b', [foo, nil]); |
630 result.checkFieldHasType('Test', 'c', [foo, nil, result.double]); | 653 result.checkFieldHasType('Test', 'c', [foo, nil, result.double]); |
631 result.checkFieldHasType('Test', 'd', [foo, nil, result.bool]); | 654 result.checkFieldHasType('Test', 'd', [foo, nil, result.bool]); |
632 | 655 |
633 result.checkFieldHasType('B', 'x', [result.string]); | 656 result.checkFieldHasType('B', 'x', [result.string]); |
634 result.checkFieldHasType('B', 'y', [result.bool]); | 657 result.checkFieldHasType('B', 'y', [result.bool]); |
635 result.checkFieldHasType('Test', 'e', [foo, result.string]); | 658 result.checkFieldHasType('Test', 'e', [foo, result.string]); |
636 result.checkFieldHasType('Test', 'f', [foo, result.bool]); | 659 result.checkFieldHasType('Test', 'f', [foo, result.bool]); |
637 | 660 |
638 result.checkFieldHasType('C', 'x', [result.string]); | 661 result.checkFieldHasType('C', 'x', [result.string]); |
639 result.checkFieldHasType('C', 'y', [result.bool]); | 662 result.checkFieldHasType('C', 'y', [result.bool]); |
640 result.checkFieldHasType('Test', 'g', [foo, result.string]); | 663 result.checkFieldHasType('Test', 'g', [foo, result.string]); |
641 result.checkFieldHasType('Test', 'h', [foo, result.bool]); | 664 result.checkFieldHasType('Test', 'h', [foo, result.bool]); |
| 665 }); |
642 } | 666 } |
643 | 667 |
644 testOptionalPositionalParameters() { | 668 testOptionalPositionalParameters() { |
645 final String source = r""" | 669 final String source = r""" |
646 class A { | 670 class A { |
647 var x, y, z, w; | 671 var x, y, z, w; |
648 A(this.x, [this.y, this.z, this.w]); | 672 A(this.x, [this.y, this.z, this.w]); |
649 } | 673 } |
650 class B { | 674 class B { |
651 var x, y; | 675 var x, y; |
(...skipping 29 matching lines...) Expand all Loading... |
681 new A('abc', true, 42.0); | 705 new A('abc', true, 42.0); |
682 test.f1(42); | 706 test.f1(42); |
683 test.f1('abc', true, 42.0); | 707 test.f1('abc', true, 42.0); |
684 | 708 |
685 new B('a', true); | 709 new B('a', true); |
686 new B(1, 2, 3); // too many arguments | 710 new B(1, 2, 3); // too many arguments |
687 test.f2('a', true); | 711 test.f2('a', true); |
688 test.f2(1, 2, 3); // too many arguments | 712 test.f2(1, 2, 3); // too many arguments |
689 } | 713 } |
690 """; | 714 """; |
691 AnalysisResult result = analyze(source); | 715 analyze(source).then((result) { |
692 | 716 |
693 final foo = result.base('Foo'); | 717 final foo = result.base('Foo'); |
694 final nil = result.nullType; | 718 final nil = result.nullType; |
695 | 719 |
696 result.checkFieldHasType('A', 'x', [result.int, result.string]); | 720 result.checkFieldHasType('A', 'x', [result.int, result.string]); |
697 result.checkFieldHasType('A', 'y', [nil, result.bool]); | 721 result.checkFieldHasType('A', 'y', [nil, result.bool]); |
698 result.checkFieldHasType('A', 'z', [nil, result.double]); | 722 result.checkFieldHasType('A', 'z', [nil, result.double]); |
699 result.checkFieldHasType('A', 'w', [nil]); | 723 result.checkFieldHasType('A', 'w', [nil]); |
700 result.checkFieldHasType('Test', 'a', [foo, result.int, result.string]); | 724 result.checkFieldHasType('Test', 'a', [foo, result.int, result.string]); |
701 result.checkFieldHasType('Test', 'b', [foo, nil, result.bool]); | 725 result.checkFieldHasType('Test', 'b', [foo, nil, result.bool]); |
702 result.checkFieldHasType('Test', 'c', [foo, nil, result.double]); | 726 result.checkFieldHasType('Test', 'c', [foo, nil, result.double]); |
703 result.checkFieldHasType('Test', 'd', [foo, nil]); | 727 result.checkFieldHasType('Test', 'd', [foo, nil]); |
704 | 728 |
705 result.checkFieldHasType('B', 'x', [result.string]); | 729 result.checkFieldHasType('B', 'x', [result.string]); |
706 result.checkFieldHasType('B', 'y', [result.bool]); | 730 result.checkFieldHasType('B', 'y', [result.bool]); |
707 result.checkFieldHasType('Test', 'e', [foo, result.string]); | 731 result.checkFieldHasType('Test', 'e', [foo, result.string]); |
708 result.checkFieldHasType('Test', 'f', [foo, result.bool]); | 732 result.checkFieldHasType('Test', 'f', [foo, result.bool]); |
| 733 }); |
709 } | 734 } |
710 | 735 |
711 testListLiterals() { | 736 testListLiterals() { |
712 final String source = r""" | 737 final String source = r""" |
713 class A { | 738 class A { |
714 var x; | 739 var x; |
715 A(this.x); | 740 A(this.x); |
716 } | 741 } |
717 main() { | 742 main() { |
718 var x = []; | 743 var x = []; |
719 var y = [1, "a", null, new A(42)]; | 744 var y = [1, "a", null, new A(42)]; |
720 x; y; | 745 x; y; |
721 } | 746 } |
722 """; | 747 """; |
723 AnalysisResult result = analyze(source); | 748 analyze(source).then((result) { |
724 result.checkNodeHasType('x', [result.list]); | 749 result.checkNodeHasType('x', [result.list]); |
725 result.checkNodeHasType('y', [result.list]); | 750 result.checkNodeHasType('y', [result.list]); |
726 result.checkFieldHasType('A', 'x', [result.int]); | 751 result.checkFieldHasType('A', 'x', [result.int]); |
| 752 }); |
727 } | 753 } |
728 | 754 |
729 testMapLiterals() { | 755 testMapLiterals() { |
730 final String source = r""" | 756 final String source = r""" |
731 class A { | 757 class A { |
732 var x; | 758 var x; |
733 A(this.x); | 759 A(this.x); |
734 } | 760 } |
735 main() { | 761 main() { |
736 var x = {}; | 762 var x = {}; |
737 var y = {'a': "foo", 'b': new A(42) }; | 763 var y = {'a': "foo", 'b': new A(42) }; |
738 x; y; | 764 x; y; |
739 } | 765 } |
740 """; | 766 """; |
741 AnalysisResult result = analyze(source); | 767 analyze(source).then((result) { |
742 result.checkNodeHasType('x', [result.map]); | 768 result.checkNodeHasType('x', [result.map]); |
743 result.checkNodeHasType('y', [result.map]); | 769 result.checkNodeHasType('y', [result.map]); |
744 result.checkFieldHasType('A', 'x', [result.int]); | 770 result.checkFieldHasType('A', 'x', [result.int]); |
| 771 }); |
745 } | 772 } |
746 | 773 |
747 testReturn() { | 774 testReturn() { |
748 final String source = r""" | 775 final String source = r""" |
749 f() { if (true) { return 1; }; return "a"; } | 776 f() { if (true) { return 1; }; return "a"; } |
750 g() { f(); return; } | 777 g() { f(); return; } |
751 main() { | 778 main() { |
752 var x = f(); | 779 var x = f(); |
753 var y = g(); | 780 var y = g(); |
754 x; y; | 781 x; y; |
755 } | 782 } |
756 """; | 783 """; |
757 AnalysisResult result = analyze(source); | 784 analyze(source).then((result) { |
758 result.checkNodeHasType('x', [result.int, result.string]); | 785 result.checkNodeHasType('x', [result.int, result.string]); |
759 result.checkNodeHasType('y', [result.nullType]); | 786 result.checkNodeHasType('y', [result.nullType]); |
| 787 }); |
760 } | 788 } |
761 | 789 |
762 testNoReturn() { | 790 testNoReturn() { |
763 final String source = r""" | 791 final String source = r""" |
764 f() { if (true) { return 1; }; } | 792 f() { if (true) { return 1; }; } |
765 g() { f(); } | 793 g() { f(); } |
766 main() { | 794 main() { |
767 var x = f(); | 795 var x = f(); |
768 var y = g(); | 796 var y = g(); |
769 x; y; | 797 x; y; |
770 } | 798 } |
771 """; | 799 """; |
772 AnalysisResult result = analyze(source); | 800 analyze(source).then((result) { |
773 result.checkNodeHasType('x', [result.int, result.nullType]); | 801 result.checkNodeHasType('x', [result.int, result.nullType]); |
774 result.checkNodeHasType('y', [result.nullType]); | 802 result.checkNodeHasType('y', [result.nullType]); |
| 803 }); |
775 } | 804 } |
776 | 805 |
777 testArithmeticOperators() { | 806 testArithmeticOperators() { |
778 String source(op) { | 807 String source(op) { |
779 return """ | 808 return """ |
780 main() { | 809 main() { |
781 var a = 1 $op 2; | 810 var a = 1 $op 2; |
782 var b = 1 $op 2.0; | 811 var b = 1 $op 2.0; |
783 var c = 1.0 $op 2; | 812 var c = 1.0 $op 2; |
784 var d = 1.0 $op 2.0; | 813 var d = 1.0 $op 2.0; |
785 var e = (1 $op 2.0) $op 1; | 814 var e = (1 $op 2.0) $op 1; |
786 var f = 1 $op (1 $op 2.0); | 815 var f = 1 $op (1 $op 2.0); |
787 var g = (1 $op 2.0) $op 1.0; | 816 var g = (1 $op 2.0) $op 1.0; |
788 var h = 1.0 $op (1 $op 2); | 817 var h = 1.0 $op (1 $op 2); |
789 var i = (1 $op 2) $op 1; | 818 var i = (1 $op 2) $op 1; |
790 var j = 1 $op (1 $op 2); | 819 var j = 1 $op (1 $op 2); |
791 var k = (1.0 $op 2.0) $op 1.0; | 820 var k = (1.0 $op 2.0) $op 1.0; |
792 var l = 1.0 $op (1.0 $op 2.0); | 821 var l = 1.0 $op (1.0 $op 2.0); |
793 a; b; c; d; e; f; g; h; i; j; k; l; | 822 a; b; c; d; e; f; g; h; i; j; k; l; |
794 }"""; | 823 }"""; |
795 } | 824 } |
796 for (String op in ['+', '*', '-']) { | 825 for (String op in ['+', '*', '-']) { |
797 AnalysisResult result = analyze(source(op)); | 826 analyze(source(op)).then((result) { |
798 result.checkNodeHasType('a', [result.int]); | 827 result.checkNodeHasType('a', [result.int]); |
799 result.checkNodeHasType('b', [result.num]); | 828 result.checkNodeHasType('b', [result.num]); |
800 result.checkNodeHasType('c', [result.num]); | 829 result.checkNodeHasType('c', [result.num]); |
801 result.checkNodeHasType('d', [result.double]); | 830 result.checkNodeHasType('d', [result.double]); |
802 result.checkNodeHasType('e', [result.num]); | 831 result.checkNodeHasType('e', [result.num]); |
803 result.checkNodeHasType('f', [result.num]); | 832 result.checkNodeHasType('f', [result.num]); |
804 result.checkNodeHasType('g', [result.num]); | 833 result.checkNodeHasType('g', [result.num]); |
805 result.checkNodeHasType('h', [result.num]); | 834 result.checkNodeHasType('h', [result.num]); |
806 result.checkNodeHasType('i', [result.int]); | 835 result.checkNodeHasType('i', [result.int]); |
807 result.checkNodeHasType('j', [result.int]); | 836 result.checkNodeHasType('j', [result.int]); |
808 result.checkNodeHasType('k', [result.double]); | 837 result.checkNodeHasType('k', [result.double]); |
809 result.checkNodeHasType('l', [result.double]); | 838 result.checkNodeHasType('l', [result.double]); |
| 839 }); |
810 } | 840 } |
811 } | 841 } |
812 | 842 |
813 testBooleanOperators() { | 843 testBooleanOperators() { |
814 String source(op) { | 844 String source(op) { |
815 return """ | 845 return """ |
816 main() { | 846 main() { |
817 var a = true $op null; | 847 var a = true $op null; |
818 var b = null $op true; | 848 var b = null $op true; |
819 var c = 1 $op true; | 849 var c = 1 $op true; |
820 var d = true $op "a"; | 850 var d = true $op "a"; |
821 a; b; c; d; | 851 a; b; c; d; |
822 }"""; | 852 }"""; |
823 } | 853 } |
824 for (String op in ['&&', '||']) { | 854 for (String op in ['&&', '||']) { |
825 AnalysisResult result = analyze(source(op)); | 855 analyze(source(op)).then((result) { |
826 result.checkNodeHasType('a', [result.bool]); | 856 result.checkNodeHasType('a', [result.bool]); |
827 result.checkNodeHasType('b', [result.bool]); | 857 result.checkNodeHasType('b', [result.bool]); |
828 result.checkNodeHasType('c', [result.bool]); | 858 result.checkNodeHasType('c', [result.bool]); |
829 result.checkNodeHasType('d', [result.bool]); | 859 result.checkNodeHasType('d', [result.bool]); |
| 860 }); |
830 } | 861 } |
831 } | 862 } |
832 | 863 |
833 testOperators() { | 864 testOperators() { |
834 final String source = r""" | 865 final String source = r""" |
835 class A { | 866 class A { |
836 operator <(x) => 42; | 867 operator <(x) => 42; |
837 operator <<(x) => "a"; | 868 operator <<(x) => "a"; |
838 } | 869 } |
839 main() { | 870 main() { |
840 var x = new A() < "foo"; | 871 var x = new A() < "foo"; |
841 var y = new A() << "foo"; | 872 var y = new A() << "foo"; |
842 x; y; | 873 x; y; |
843 } | 874 } |
844 """; | 875 """; |
845 AnalysisResult result = analyze(source); | 876 analyze(source).then((result) { |
846 result.checkNodeHasType('x', [result.int]); | 877 result.checkNodeHasType('x', [result.int]); |
847 result.checkNodeHasType('y', [result.string]); | 878 result.checkNodeHasType('y', [result.string]); |
| 879 }); |
848 } | 880 } |
849 | 881 |
850 testSetIndexOperator() { | 882 testSetIndexOperator() { |
851 final String source = r""" | 883 final String source = r""" |
852 class A { | 884 class A { |
853 var witness1; | 885 var witness1; |
854 var witness2; | 886 var witness2; |
855 operator []=(i, x) { witness1 = i; witness2 = x; } | 887 operator []=(i, x) { witness1 = i; witness2 = x; } |
856 } | 888 } |
857 main() { | 889 main() { |
858 var x = new A()[42] = "abc"; | 890 var x = new A()[42] = "abc"; |
859 x; | 891 x; |
860 } | 892 } |
861 """; | 893 """; |
862 AnalysisResult result = analyze(source); | 894 analyze(source).then((result) { |
863 result.checkNodeHasType('x', [result.string]); | 895 result.checkNodeHasType('x', [result.string]); |
864 result.checkFieldHasType('A', 'witness1', [result.int, result.nullType]); | 896 result.checkFieldHasType('A', 'witness1', [result.int, result.nullType]); |
865 result.checkFieldHasType('A', 'witness2', [result.string, result.nullType]); | 897 result.checkFieldHasType('A', 'witness2', [result.string, result.nullType]); |
| 898 }); |
866 } | 899 } |
867 | 900 |
868 testCompoundOperators1() { | 901 testCompoundOperators1() { |
869 final String source = r""" | 902 final String source = r""" |
870 class A { | 903 class A { |
871 operator +(x) => "foo"; | 904 operator +(x) => "foo"; |
872 } | 905 } |
873 main() { | 906 main() { |
874 var x1 = 1; | 907 var x1 = 1; |
875 x1++; | 908 x1++; |
876 var x2 = 1; | 909 var x2 = 1; |
877 ++x2; | 910 ++x2; |
878 var x3 = 1; | 911 var x3 = 1; |
879 x3 += 42; | 912 x3 += 42; |
880 var x4 = new A(); | 913 var x4 = new A(); |
881 x4++; | 914 x4++; |
882 var x5 = new A(); | 915 var x5 = new A(); |
883 ++x5; | 916 ++x5; |
884 var x6 = new A(); | 917 var x6 = new A(); |
885 x6 += true; | 918 x6 += true; |
886 | 919 |
887 x1; x2; x3; x4; x5; x6; | 920 x1; x2; x3; x4; x5; x6; |
888 } | 921 } |
889 """; | 922 """; |
890 AnalysisResult result = analyze(source); | 923 analyze(source).then((result) { |
891 result.checkNodeHasType('x1', [result.int]); | 924 result.checkNodeHasType('x1', [result.int]); |
892 result.checkNodeHasType('x2', [result.int]); | 925 result.checkNodeHasType('x2', [result.int]); |
893 result.checkNodeHasType('x3', [result.int]); | 926 result.checkNodeHasType('x3', [result.int]); |
894 result.checkNodeHasType('x4', [result.string]); | 927 result.checkNodeHasType('x4', [result.string]); |
895 result.checkNodeHasType('x5', [result.string]); | 928 result.checkNodeHasType('x5', [result.string]); |
896 result.checkNodeHasType('x6', [result.string]); | 929 result.checkNodeHasType('x6', [result.string]); |
| 930 }); |
897 } | 931 } |
898 | 932 |
899 | 933 |
900 testCompoundOperators2() { | 934 testCompoundOperators2() { |
901 final String source = r""" | 935 final String source = r""" |
902 class A { | 936 class A { |
903 var xx; | 937 var xx; |
904 var yy; | 938 var yy; |
905 var witness1; | 939 var witness1; |
906 var witness2; | 940 var witness2; |
907 var witness3; | 941 var witness3; |
908 var witness4; | 942 var witness4; |
909 | 943 |
910 A(this.xx, this.yy); | 944 A(this.xx, this.yy); |
911 get x { witness1 = "foo"; return xx; } | 945 get x { witness1 = "foo"; return xx; } |
912 set x(a) { witness2 = "foo"; xx = a; } | 946 set x(a) { witness2 = "foo"; xx = a; } |
913 get y { witness3 = "foo"; return yy; } | 947 get y { witness3 = "foo"; return yy; } |
914 set y(a) { witness4 = "foo"; yy = a; } | 948 set y(a) { witness4 = "foo"; yy = a; } |
915 } | 949 } |
916 main () { | 950 main () { |
917 var a = new A(1, 1); | 951 var a = new A(1, 1); |
918 a.x++; | 952 a.x++; |
919 a.y++; | 953 a.y++; |
920 } | 954 } |
921 """; | 955 """; |
922 AnalysisResult result = analyze(source); | 956 analyze(source).then((result) { |
923 result.checkFieldHasType('A', 'xx', [result.int]); | 957 result.checkFieldHasType('A', 'xx', [result.int]); |
924 result.checkFieldHasType('A', 'yy', [result.int]); | 958 result.checkFieldHasType('A', 'yy', [result.int]); |
925 result.checkFieldHasType('A', 'witness1', [result.string, result.nullType]); | 959 result.checkFieldHasType('A', 'witness1', [result.string, result.nullType]); |
926 result.checkFieldHasType('A', 'witness2', [result.string, result.nullType]); | 960 result.checkFieldHasType('A', 'witness2', [result.string, result.nullType]); |
927 result.checkFieldHasType('A', 'witness3', [result.string, result.nullType]); | 961 result.checkFieldHasType('A', 'witness3', [result.string, result.nullType]); |
928 result.checkFieldHasType('A', 'witness4', [result.string, result.nullType]); | 962 result.checkFieldHasType('A', 'witness4', [result.string, result.nullType]); |
| 963 }); |
929 } | 964 } |
930 | 965 |
931 testInequality() { | 966 testInequality() { |
932 final String source = r""" | 967 final String source = r""" |
933 class A { | 968 class A { |
934 var witness; | 969 var witness; |
935 operator ==(x) { witness = "foo"; return "abc"; } | 970 operator ==(x) { witness = "foo"; return "abc"; } |
936 } | 971 } |
937 class B { | 972 class B { |
938 operator ==(x) { throw "error"; } | 973 operator ==(x) { throw "error"; } |
939 } | 974 } |
940 main() { | 975 main() { |
941 var foo = 1 != 2; | 976 var foo = 1 != 2; |
942 var bar = new A() != 2; | 977 var bar = new A() != 2; |
943 var baz = new B() != 2; | 978 var baz = new B() != 2; |
944 foo; bar; baz; | 979 foo; bar; baz; |
945 } | 980 } |
946 """; | 981 """; |
947 AnalysisResult result = analyze(source); | 982 analyze(source).then((result) { |
948 result.checkNodeHasType('foo', [result.bool]); | 983 result.checkNodeHasType('foo', [result.bool]); |
949 result.checkNodeHasType('bar', [result.bool]); | 984 result.checkNodeHasType('bar', [result.bool]); |
950 result.checkNodeHasType('baz', []); | 985 result.checkNodeHasType('baz', []); |
951 result.checkFieldHasType('A', 'witness', [result.string, result.nullType]); | 986 result.checkFieldHasType('A', 'witness', [result.string, result.nullType]); |
| 987 }); |
952 } | 988 } |
953 | 989 |
954 testFieldInitialization1() { | 990 testFieldInitialization1() { |
955 final String source = r""" | 991 final String source = r""" |
956 class A { | 992 class A { |
957 var x; | 993 var x; |
958 var y = 1; | 994 var y = 1; |
959 } | 995 } |
960 class B extends A { | 996 class B extends A { |
961 var z = "foo"; | 997 var z = "foo"; |
962 } | 998 } |
963 main () { | 999 main () { |
964 new B(); | 1000 new B(); |
965 } | 1001 } |
966 """; | 1002 """; |
967 AnalysisResult result = analyze(source); | 1003 analyze(source).then((result) { |
968 result.checkFieldHasType('A', 'x', [result.nullType]); | 1004 result.checkFieldHasType('A', 'x', [result.nullType]); |
969 result.checkFieldHasType('A', 'y', [result.int]); | 1005 result.checkFieldHasType('A', 'y', [result.int]); |
970 result.checkFieldHasType('B', 'z', [result.string]); | 1006 result.checkFieldHasType('B', 'z', [result.string]); |
| 1007 }); |
971 } | 1008 } |
972 | 1009 |
973 testFieldInitialization2() { | 1010 testFieldInitialization2() { |
974 final String source = r""" | 1011 final String source = r""" |
975 var top = 42; | 1012 var top = 42; |
976 class A { | 1013 class A { |
977 var x = top; | 1014 var x = top; |
978 } | 1015 } |
979 main () { | 1016 main () { |
980 new A(); | 1017 new A(); |
981 } | 1018 } |
982 """; | 1019 """; |
983 AnalysisResult result = analyze(source); | 1020 analyze(source).then((result) { |
984 result.checkFieldHasType('A', 'x', [result.int]); | 1021 result.checkFieldHasType('A', 'x', [result.int]); |
| 1022 }); |
985 } | 1023 } |
986 | 1024 |
987 testFieldInitialization3() { | 1025 testFieldInitialization3() { |
988 final String source = r""" | 1026 final String source = r""" |
989 class A { | 1027 class A { |
990 var x; | 1028 var x; |
991 } | 1029 } |
992 f() => new A().x; | 1030 f() => new A().x; |
993 class B { | 1031 class B { |
994 var x = new A().x; | 1032 var x = new A().x; |
995 var y = f(); | 1033 var y = f(); |
996 } | 1034 } |
997 main () { | 1035 main () { |
998 var foo = new B().x; | 1036 var foo = new B().x; |
999 var bar = new B().y; | 1037 var bar = new B().y; |
1000 new A().x = "a"; | 1038 new A().x = "a"; |
1001 foo; bar; | 1039 foo; bar; |
1002 } | 1040 } |
1003 """; | 1041 """; |
1004 AnalysisResult result = analyze(source); | 1042 analyze(source).then((result) { |
1005 // checks that B.B is set as a reader of A.x | 1043 // checks that B.B is set as a reader of A.x |
1006 result.checkFieldHasType('B', 'x', [result.nullType, result.string]); | 1044 result.checkFieldHasType('B', 'x', [result.nullType, result.string]); |
1007 // checks that B.B is set as a caller of f | 1045 // checks that B.B is set as a caller of f |
1008 result.checkFieldHasType('B', 'y', [result.nullType, result.string]); | 1046 result.checkFieldHasType('B', 'y', [result.nullType, result.string]); |
1009 // checks that readers of x are notified by changes in x's type | 1047 // checks that readers of x are notified by changes in x's type |
1010 result.checkNodeHasType('foo', [result.nullType, result.string]); | 1048 result.checkNodeHasType('foo', [result.nullType, result.string]); |
1011 // checks that readers of y are notified by changes in y's type | 1049 // checks that readers of y are notified by changes in y's type |
1012 result.checkNodeHasType('bar', [result.nullType, result.string]); | 1050 result.checkNodeHasType('bar', [result.nullType, result.string]); |
| 1051 }); |
1013 } | 1052 } |
1014 | 1053 |
1015 testLists() { | 1054 testLists() { |
1016 final String source = r""" | 1055 final String source = r""" |
1017 main() { | 1056 main() { |
1018 new List(); | 1057 new List(); |
1019 var l1 = [1.2]; | 1058 var l1 = [1.2]; |
1020 var l2 = []; | 1059 var l2 = []; |
1021 l1['a'] = 42; // raises an error, so int should not be recorded | 1060 l1['a'] = 42; // raises an error, so int should not be recorded |
1022 l1[1] = 'abc'; | 1061 l1[1] = 'abc'; |
1023 "__dynamic_for_test"[1] = true; | 1062 "__dynamic_for_test"[1] = true; |
1024 var x = l1[1]; | 1063 var x = l1[1]; |
1025 var y = l2[1]; | 1064 var y = l2[1]; |
1026 var z = l1['foo']; | 1065 var z = l1['foo']; |
1027 x; y; z; | 1066 x; y; z; |
1028 }"""; | 1067 }"""; |
1029 AnalysisResult result = analyze(source); | 1068 analyze(source).then((result) { |
1030 result.checkNodeHasType('x', [result.double, result.string, result.bool]); | 1069 result.checkNodeHasType('x', [result.double, result.string, result.bool]); |
1031 result.checkNodeHasType('y', [result.double, result.string, result.bool]); | 1070 result.checkNodeHasType('y', [result.double, result.string, result.bool]); |
1032 result.checkNodeHasType('z', []); | 1071 result.checkNodeHasType('z', []); |
| 1072 }); |
1033 } | 1073 } |
1034 | 1074 |
1035 testListWithCapacity() { | 1075 testListWithCapacity() { |
1036 final String source = r""" | 1076 final String source = r""" |
1037 main() { | 1077 main() { |
1038 var l = new List(10); | 1078 var l = new List(10); |
1039 var x = l[0]; | 1079 var x = l[0]; |
1040 x; | 1080 x; |
1041 }"""; | 1081 }"""; |
1042 AnalysisResult result = analyze(source); | 1082 analyze(source).then((result) { |
1043 result.checkNodeHasType('x', [result.nullType]); | 1083 result.checkNodeHasType('x', [result.nullType]); |
| 1084 }); |
1044 } | 1085 } |
1045 | 1086 |
1046 testEmptyList() { | 1087 testEmptyList() { |
1047 final String source = r""" | 1088 final String source = r""" |
1048 main() { | 1089 main() { |
1049 var l = new List(); | 1090 var l = new List(); |
1050 var x = l[0]; | 1091 var x = l[0]; |
1051 x; | 1092 x; |
1052 }"""; | 1093 }"""; |
1053 AnalysisResult result = analyze(source); | 1094 analyze(source).then((result) { |
1054 result.checkNodeHasType('x', []); | 1095 result.checkNodeHasType('x', []); |
| 1096 }); |
1055 } | 1097 } |
1056 | 1098 |
1057 testSendWithWrongArity() { | 1099 testSendWithWrongArity() { |
1058 final String source = r""" | 1100 final String source = r""" |
1059 f(x) { } | 1101 f(x) { } |
1060 class A { g(x) { } } | 1102 class A { g(x) { } } |
1061 main () { | 1103 main () { |
1062 var x = f(); | 1104 var x = f(); |
1063 var y = f(1, 2); | 1105 var y = f(1, 2); |
1064 var z = new A().g(); | 1106 var z = new A().g(); |
1065 var w = new A().g(1, 2); | 1107 var w = new A().g(1, 2); |
1066 x; y; z; w; | 1108 x; y; z; w; |
1067 } | 1109 } |
1068 """; | 1110 """; |
1069 AnalysisResult result = analyze(source); | 1111 analyze(source).then((result) { |
1070 result.checkNodeHasType('x', []); | 1112 result.checkNodeHasType('x', []); |
1071 result.checkNodeHasType('y', []); | 1113 result.checkNodeHasType('y', []); |
1072 result.checkNodeHasType('z', []); | 1114 result.checkNodeHasType('z', []); |
1073 result.checkNodeHasType('w', []); | 1115 result.checkNodeHasType('w', []); |
| 1116 }); |
1074 } | 1117 } |
1075 | 1118 |
1076 testBigTypesWidening1() { | 1119 testBigTypesWidening1() { |
1077 final String source = r""" | 1120 final String source = r""" |
1078 small() => true ? 1 : 'abc'; | 1121 small() => true ? 1 : 'abc'; |
1079 big() => true ? 1 : (true ? 'abc' : false); | 1122 big() => true ? 1 : (true ? 'abc' : false); |
1080 main () { | 1123 main () { |
1081 var x = small(); | 1124 var x = small(); |
1082 var y = big(); | 1125 var y = big(); |
1083 x; y; | 1126 x; y; |
1084 } | 1127 } |
1085 """; | 1128 """; |
1086 AnalysisResult result = analyze(source, maxConcreteTypeSize: 2); | 1129 analyze(source, maxConcreteTypeSize: 2).then((result) { |
1087 result.checkNodeHasType('x', [result.int, result.string]); | 1130 result.checkNodeHasType('x', [result.int, result.string]); |
1088 result.checkNodeHasUnknownType('y'); | 1131 result.checkNodeHasUnknownType('y'); |
| 1132 }); |
1089 } | 1133 } |
1090 | 1134 |
1091 testBigTypesWidening2() { | 1135 testBigTypesWidening2() { |
1092 final String source = r""" | 1136 final String source = r""" |
1093 class A { | 1137 class A { |
1094 var x, y; | 1138 var x, y; |
1095 A(this.x, this.y); | 1139 A(this.x, this.y); |
1096 } | 1140 } |
1097 main () { | 1141 main () { |
1098 var a = new A(1, 1); | 1142 var a = new A(1, 1); |
1099 a.x = 'abc'; | 1143 a.x = 'abc'; |
1100 a.y = 'abc'; | 1144 a.y = 'abc'; |
1101 a.y = true; | 1145 a.y = true; |
1102 } | 1146 } |
1103 """; | 1147 """; |
1104 AnalysisResult result = analyze(source, maxConcreteTypeSize: 2); | 1148 analyze(source, maxConcreteTypeSize: 2).then((result) { |
1105 result.checkFieldHasType('A', 'x', [result.int, result.string]); | 1149 result.checkFieldHasType('A', 'x', [result.int, result.string]); |
1106 result.checkFieldHasUknownType('A', 'y'); | 1150 result.checkFieldHasUknownType('A', 'y'); |
| 1151 }); |
1107 } | 1152 } |
1108 | 1153 |
1109 testDynamicIsAbsorbing() { | 1154 testDynamicIsAbsorbing() { |
1110 final String source = r""" | 1155 final String source = r""" |
1111 main () { | 1156 main () { |
1112 var x = 1; | 1157 var x = 1; |
1113 if (true) { | 1158 if (true) { |
1114 x = "__dynamic_for_test"; | 1159 x = "__dynamic_for_test"; |
1115 } else { | 1160 } else { |
1116 x = 42; | 1161 x = 42; |
1117 } | 1162 } |
1118 x; | 1163 x; |
1119 } | 1164 } |
1120 """; | 1165 """; |
1121 AnalysisResult result = analyze(source); | 1166 analyze(source).then((result) { |
1122 result.checkNodeHasUnknownType('x'); | 1167 result.checkNodeHasUnknownType('x'); |
| 1168 }); |
1123 } | 1169 } |
1124 | 1170 |
1125 testJsCall() { | 1171 testJsCall() { |
1126 final String source = r""" | 1172 final String source = r""" |
1127 import 'dart:foreign'; | 1173 import 'dart:foreign'; |
1128 import 'dart:interceptors'; | 1174 import 'dart:interceptors'; |
1129 | 1175 |
1130 class A {} | 1176 class A {} |
1131 class B extends A {} | 1177 class B extends A {} |
1132 class BB extends B {} | 1178 class BB extends B {} |
(...skipping 12 matching lines...) Expand all Loading... |
1145 var d = JS('String', '1'); | 1191 var d = JS('String', '1'); |
1146 var e = JS('int', '1'); | 1192 var e = JS('int', '1'); |
1147 var f = JS('double', '1'); | 1193 var f = JS('double', '1'); |
1148 var g = JS('num', '1'); | 1194 var g = JS('num', '1'); |
1149 var h = JS('bool', '1'); | 1195 var h = JS('bool', '1'); |
1150 var i = JS('A', '1'); | 1196 var i = JS('A', '1'); |
1151 var j = JS('X', '1'); | 1197 var j = JS('X', '1'); |
1152 a; b; c; d; e; f; g; h; i; j; | 1198 a; b; c; d; e; f; g; h; i; j; |
1153 } | 1199 } |
1154 """; | 1200 """; |
1155 AnalysisResult result = analyze(source); | 1201 analyze(source).then((result) { |
1156 result.checkNodeHasUnknownType('a'); | 1202 result.checkNodeHasUnknownType('a'); |
1157 result.checkNodeHasUnknownType('b'); | 1203 result.checkNodeHasUnknownType('b'); |
1158 // TODO(polux): Fix this test. | 1204 // TODO(polux): Fix this test. |
1159 // result.checkNodeHasType('c', [result.nullType, result.list]); | 1205 // result.checkNodeHasType('c', [result.nullType, result.list]); |
1160 result.checkNodeHasType('d', [result.nullType, result.string]); | 1206 result.checkNodeHasType('d', [result.nullType, result.string]); |
1161 result.checkNodeHasType('e', [result.nullType, result.int]); | 1207 result.checkNodeHasType('e', [result.nullType, result.int]); |
1162 result.checkNodeHasType('f', [result.nullType, result.double]); | 1208 result.checkNodeHasType('f', [result.nullType, result.double]); |
1163 result.checkNodeHasType('g', [result.nullType, result.num]); | 1209 result.checkNodeHasType('g', [result.nullType, result.num]); |
1164 result.checkNodeHasType('h', [result.nullType, result.bool]); | 1210 result.checkNodeHasType('h', [result.nullType, result.bool]); |
1165 result.checkNodeHasType('i', [result.nullType, result.base('B'), | 1211 result.checkNodeHasType('i', [result.nullType, result.base('B'), |
1166 result.base('BB'), result.base('C')]); | 1212 result.base('BB'), result.base('C')]); |
1167 result.checkNodeHasType('j', [result.nullType]); | 1213 result.checkNodeHasType('j', [result.nullType]); |
| 1214 }); |
1168 } | 1215 } |
1169 | 1216 |
1170 testIsCheck() { | 1217 testIsCheck() { |
1171 final String source = r""" | 1218 final String source = r""" |
1172 main () { | 1219 main () { |
1173 var x = (1 is String); | 1220 var x = (1 is String); |
1174 x; | 1221 x; |
1175 } | 1222 } |
1176 """; | 1223 """; |
1177 AnalysisResult result = analyze(source); | 1224 analyze(source).then((result) { |
1178 result.checkNodeHasType('x', [result.bool]); | 1225 result.checkNodeHasType('x', [result.bool]); |
| 1226 }); |
1179 } | 1227 } |
1180 | 1228 |
1181 testSeenClasses() { | 1229 testSeenClasses() { |
1182 final String source = r""" | 1230 final String source = r""" |
1183 class A { | 1231 class A { |
1184 witness() => 42; | 1232 witness() => 42; |
1185 } | 1233 } |
1186 class B { | 1234 class B { |
1187 witness() => "abc"; | 1235 witness() => "abc"; |
1188 } | 1236 } |
1189 class AFactory { | 1237 class AFactory { |
1190 onlyCalledInAFactory() => new A(); | 1238 onlyCalledInAFactory() => new A(); |
1191 } | 1239 } |
1192 class BFactory { | 1240 class BFactory { |
1193 onlyCalledInAFactory() => new B(); | 1241 onlyCalledInAFactory() => new B(); |
1194 } | 1242 } |
1195 | 1243 |
1196 main() { | 1244 main() { |
1197 new AFactory().onlyCalledInAFactory(); | 1245 new AFactory().onlyCalledInAFactory(); |
1198 new BFactory(); | 1246 new BFactory(); |
1199 // should be of type {int} and not {int, String} since B is unreachable | 1247 // should be of type {int} and not {int, String} since B is unreachable |
1200 var foo = "__dynamic_for_test".witness(); | 1248 var foo = "__dynamic_for_test".witness(); |
1201 foo; | 1249 foo; |
1202 } | 1250 } |
1203 """; | 1251 """; |
1204 AnalysisResult result = analyze(source); | 1252 analyze(source).then((result) { |
1205 result.checkNodeHasType('foo', [result.int]); | 1253 result.checkNodeHasType('foo', [result.int]); |
| 1254 }); |
1206 } | 1255 } |
1207 | 1256 |
1208 testIntDoubleNum() { | 1257 testIntDoubleNum() { |
1209 final String source = r""" | 1258 final String source = r""" |
1210 main() { | 1259 main() { |
1211 var a = 1; | 1260 var a = 1; |
1212 var b = 1.0; | 1261 var b = 1.0; |
1213 var c = true ? 1 : 1.0; | 1262 var c = true ? 1 : 1.0; |
1214 a; b; c; | 1263 a; b; c; |
1215 } | 1264 } |
1216 """; | 1265 """; |
1217 AnalysisResult result = analyze(source); | 1266 analyze(source).then((result) { |
1218 result.checkNodeHasType('a', [result.int]); | 1267 result.checkNodeHasType('a', [result.int]); |
1219 result.checkNodeHasType('b', [result.double]); | 1268 result.checkNodeHasType('b', [result.double]); |
1220 result.checkNodeHasType('c', [result.num]); | 1269 result.checkNodeHasType('c', [result.num]); |
| 1270 }); |
1221 } | 1271 } |
1222 | 1272 |
1223 testConcreteTypeToTypeMask() { | 1273 testConcreteTypeToTypeMask() { |
1224 final String source = r""" | 1274 final String source = r""" |
1225 class A {} | 1275 class A {} |
1226 class B extends A {} | 1276 class B extends A {} |
1227 class C extends A {} | 1277 class C extends A {} |
1228 class D implements A {} | 1278 class D implements A {} |
1229 main() { | 1279 main() { |
1230 new A(); | 1280 new A(); |
1231 new B(); | 1281 new B(); |
1232 new C(); | 1282 new C(); |
1233 new D(); | 1283 new D(); |
1234 } | 1284 } |
1235 """; | 1285 """; |
1236 AnalysisResult result = analyze(source); | 1286 analyze(source).then((result) { |
1237 | 1287 |
1238 convert(ConcreteType type) { | 1288 convert(ConcreteType type) { |
1239 return result.compiler.typesTask.concreteTypesInferrer | 1289 return result.compiler.typesTask.concreteTypesInferrer |
1240 .concreteTypeToTypeMask(type); | 1290 .concreteTypeToTypeMask(type); |
1241 } | 1291 } |
1242 | 1292 |
1243 final nullSingleton = | 1293 final nullSingleton = |
1244 result.compiler.typesTask.concreteTypesInferrer.singletonConcreteType( | 1294 result.compiler.typesTask.concreteTypesInferrer.singletonConcreteType( |
1245 new NullBaseType()); | 1295 new NullBaseType()); |
1246 | 1296 |
1247 singleton(ClassElement element) { | 1297 singleton(ClassElement element) { |
1248 return result.compiler.typesTask.concreteTypesInferrer | 1298 return result.compiler.typesTask.concreteTypesInferrer |
1249 .singletonConcreteType(new ClassBaseType(element)); | 1299 .singletonConcreteType(new ClassBaseType(element)); |
1250 } | 1300 } |
1251 | 1301 |
1252 ClassElement a = findElement(result.compiler, 'A'); | 1302 ClassElement a = findElement(result.compiler, 'A'); |
1253 ClassElement b = findElement(result.compiler, 'B'); | 1303 ClassElement b = findElement(result.compiler, 'B'); |
1254 ClassElement c = findElement(result.compiler, 'C'); | 1304 ClassElement c = findElement(result.compiler, 'C'); |
1255 ClassElement d = findElement(result.compiler, 'D'); | 1305 ClassElement d = findElement(result.compiler, 'D'); |
1256 | 1306 |
1257 for (ClassElement cls in [a, b, c, d]) { | 1307 for (ClassElement cls in [a, b, c, d]) { |
1258 Expect.equals(convert(singleton(cls)), | 1308 Expect.equals(convert(singleton(cls)), |
1259 new TypeMask.nonNullExact(cls.rawType)); | 1309 new TypeMask.nonNullExact(cls.rawType)); |
1260 } | 1310 } |
1261 | 1311 |
1262 for (ClassElement cls in [a, b, c, d]) { | 1312 for (ClassElement cls in [a, b, c, d]) { |
1263 Expect.equals(convert(singleton(cls).union(nullSingleton)), | 1313 Expect.equals(convert(singleton(cls).union(nullSingleton)), |
1264 new TypeMask.exact(cls.rawType)); | 1314 new TypeMask.exact(cls.rawType)); |
1265 } | 1315 } |
1266 | 1316 |
1267 Expect.equals(convert(singleton(a).union(singleton(b))), | 1317 Expect.equals(convert(singleton(a).union(singleton(b))), |
1268 new TypeMask.nonNullSubclass(a.rawType)); | 1318 new TypeMask.nonNullSubclass(a.rawType)); |
1269 | 1319 |
1270 Expect.equals(convert(singleton(a).union(singleton(b)).union(nullSingleton)), | 1320 Expect.equals(convert(singleton(a).union(singleton(b)).union(nullSingleton))
, |
1271 new TypeMask.subclass(a.rawType)); | 1321 new TypeMask.subclass(a.rawType)); |
1272 | 1322 |
1273 Expect.equals( | 1323 Expect.equals( |
1274 convert(singleton(b).union(singleton(d))).simplify(result.compiler), | 1324 convert(singleton(b).union(singleton(d))).simplify(result.compiler), |
1275 new TypeMask.nonNullSubtype(a.rawType)); | 1325 new TypeMask.nonNullSubtype(a.rawType)); |
| 1326 }); |
1276 } | 1327 } |
1277 | 1328 |
1278 testSelectors() { | 1329 testSelectors() { |
1279 final String source = r""" | 1330 final String source = r""" |
1280 // ABC <--- A | 1331 // ABC <--- A |
1281 // `- BC <--- B | 1332 // `- BC <--- B |
1282 // `- C | 1333 // `- C |
1283 | 1334 |
1284 class ABC {} | 1335 class ABC {} |
1285 class A extends ABC {} | 1336 class A extends ABC {} |
1286 class BC extends ABC {} | 1337 class BC extends ABC {} |
1287 class B extends BC {} | 1338 class B extends BC {} |
1288 class C extends BC {} | 1339 class C extends BC {} |
1289 | 1340 |
1290 class XY {} | 1341 class XY {} |
1291 class X extends XY { foo() => new B(); } | 1342 class X extends XY { foo() => new B(); } |
1292 class Y extends XY { foo() => new C(); } | 1343 class Y extends XY { foo() => new C(); } |
1293 class Z { foo() => new A(); } | 1344 class Z { foo() => new A(); } |
1294 | 1345 |
1295 main() { | 1346 main() { |
1296 new X().foo(); | 1347 new X().foo(); |
1297 new Y().foo(); | 1348 new Y().foo(); |
1298 new Z().foo(); | 1349 new Z().foo(); |
1299 } | 1350 } |
1300 """; | 1351 """; |
1301 AnalysisResult result = analyze(source); | 1352 analyze(source).then((result) { |
1302 | 1353 |
1303 inferredType(Selector selector) { | 1354 inferredType(Selector selector) { |
1304 return result.compiler.typesTask.concreteTypesInferrer | 1355 return result.compiler.typesTask.concreteTypesInferrer |
1305 .getTypeOfSelector(selector); | 1356 .getTypeOfSelector(selector); |
1306 } | 1357 } |
1307 | 1358 |
1308 ClassElement abc = findElement(result.compiler, 'ABC'); | 1359 ClassElement abc = findElement(result.compiler, 'ABC'); |
1309 ClassElement bc = findElement(result.compiler, 'BC'); | 1360 ClassElement bc = findElement(result.compiler, 'BC'); |
1310 ClassElement a = findElement(result.compiler, 'A'); | 1361 ClassElement a = findElement(result.compiler, 'A'); |
1311 ClassElement b = findElement(result.compiler, 'B'); | 1362 ClassElement b = findElement(result.compiler, 'B'); |
1312 ClassElement c = findElement(result.compiler, 'C'); | 1363 ClassElement c = findElement(result.compiler, 'C'); |
1313 ClassElement xy = findElement(result.compiler, 'XY'); | 1364 ClassElement xy = findElement(result.compiler, 'XY'); |
1314 ClassElement x = findElement(result.compiler, 'X'); | 1365 ClassElement x = findElement(result.compiler, 'X'); |
1315 ClassElement y = findElement(result.compiler, 'Y'); | 1366 ClassElement y = findElement(result.compiler, 'Y'); |
1316 ClassElement z = findElement(result.compiler, 'Z'); | 1367 ClassElement z = findElement(result.compiler, 'Z'); |
1317 | 1368 |
1318 Selector foo = new Selector.call(buildSourceString("foo"), null, 0); | 1369 Selector foo = new Selector.call(buildSourceString("foo"), null, 0); |
1319 | 1370 |
1320 Expect.equals( | 1371 Expect.equals( |
1321 inferredType(foo).simplify(result.compiler), | 1372 inferredType(foo).simplify(result.compiler), |
1322 new TypeMask.nonNullSubclass(abc.rawType)); | 1373 new TypeMask.nonNullSubclass(abc.rawType)); |
1323 Expect.equals( | 1374 Expect.equals( |
1324 inferredType(new TypedSelector.subclass(x.rawType, foo)), | 1375 inferredType(new TypedSelector.subclass(x.rawType, foo)), |
1325 new TypeMask.nonNullExact(b.rawType)); | 1376 new TypeMask.nonNullExact(b.rawType)); |
1326 Expect.equals( | 1377 Expect.equals( |
1327 inferredType(new TypedSelector.subclass(y.rawType, foo)), | 1378 inferredType(new TypedSelector.subclass(y.rawType, foo)), |
1328 new TypeMask.nonNullExact(c.rawType)); | 1379 new TypeMask.nonNullExact(c.rawType)); |
1329 Expect.equals( | 1380 Expect.equals( |
1330 inferredType(new TypedSelector.subclass(z.rawType, foo)), | 1381 inferredType(new TypedSelector.subclass(z.rawType, foo)), |
1331 new TypeMask.nonNullExact(a.rawType)); | 1382 new TypeMask.nonNullExact(a.rawType)); |
1332 Expect.equals( | 1383 Expect.equals( |
1333 inferredType(new TypedSelector.subclass( | 1384 inferredType(new TypedSelector.subclass( |
1334 xy.rawType, foo)).simplify(result.compiler), | 1385 xy.rawType, foo)).simplify(result.compiler), |
1335 new TypeMask.nonNullSubclass(bc.rawType)); | 1386 new TypeMask.nonNullSubclass(bc.rawType)); |
1336 | 1387 |
1337 Selector bar = new Selector.call(buildSourceString("bar"), null, 0); | 1388 Selector bar = new Selector.call(buildSourceString("bar"), null, 0); |
1338 | 1389 |
1339 Expect.isNull(inferredType(bar)); | 1390 Expect.isNull(inferredType(bar)); |
| 1391 }); |
1340 } | 1392 } |
1341 | 1393 |
1342 testMixins() { | 1394 testMixins() { |
1343 final String source = r""" | 1395 final String source = r""" |
1344 class A { | 1396 class A { |
1345 foo() => "abc"; | 1397 foo() => "abc"; |
1346 get x => 42; | 1398 get x => 42; |
1347 } | 1399 } |
1348 class B extends Object with A { | 1400 class B extends Object with A { |
1349 bar() => foo(); | 1401 bar() => foo(); |
1350 baz() => x; | 1402 baz() => x; |
1351 } | 1403 } |
1352 main() { | 1404 main() { |
1353 var b = new B(); | 1405 var b = new B(); |
1354 var x = b.foo(); | 1406 var x = b.foo(); |
1355 var y = b.bar(); | 1407 var y = b.bar(); |
1356 var z = b.x; | 1408 var z = b.x; |
1357 var w = b.baz(); | 1409 var w = b.baz(); |
1358 x; y; z; w; | 1410 x; y; z; w; |
1359 } | 1411 } |
1360 """; | 1412 """; |
1361 AnalysisResult result = analyze(source); | 1413 analyze(source).then((result) { |
1362 result.checkNodeHasType('x', [result.string]); | 1414 result.checkNodeHasType('x', [result.string]); |
1363 result.checkNodeHasType('y', [result.string]); | 1415 result.checkNodeHasType('y', [result.string]); |
1364 result.checkNodeHasType('z', [result.int]); | 1416 result.checkNodeHasType('z', [result.int]); |
1365 result.checkNodeHasType('w', [result.int]); | 1417 result.checkNodeHasType('w', [result.int]); |
| 1418 }); |
1366 } | 1419 } |
1367 | 1420 |
1368 void main() { | 1421 void main() { |
1369 testDynamicBackDoor(); | 1422 testDynamicBackDoor(); |
1370 testVariableDeclaration(); | 1423 testVariableDeclaration(); |
1371 testLiterals(); | 1424 testLiterals(); |
1372 testRedefinition(); | 1425 testRedefinition(); |
1373 testIfThenElse(); | 1426 testIfThenElse(); |
1374 testTernaryIf(); | 1427 testTernaryIf(); |
1375 testWhile(); | 1428 testWhile(); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1411 testListWithCapacity(); | 1464 testListWithCapacity(); |
1412 testEmptyList(); | 1465 testEmptyList(); |
1413 testJsCall(); | 1466 testJsCall(); |
1414 testIsCheck(); | 1467 testIsCheck(); |
1415 testSeenClasses(); | 1468 testSeenClasses(); |
1416 testIntDoubleNum(); | 1469 testIntDoubleNum(); |
1417 testConcreteTypeToTypeMask(); | 1470 testConcreteTypeToTypeMask(); |
1418 testSelectors(); | 1471 testSelectors(); |
1419 testMixins(); | 1472 testMixins(); |
1420 } | 1473 } |
OLD | NEW |