OLD | NEW |
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 library world_test; | 5 library world_test; |
6 | 6 |
7 import 'package:expect/expect.dart'; | 7 import 'package:expect/expect.dart'; |
8 import 'package:async_helper/async_helper.dart'; | 8 import 'package:async_helper/async_helper.dart'; |
9 import 'type_test_helper.dart'; | 9 import 'type_test_helper.dart'; |
10 import 'package:compiler/src/common.dart'; | 10 import 'package:compiler/src/common/names.dart'; |
11 import 'package:compiler/src/elements/elements.dart' show Element, ClassElement; | 11 import 'package:compiler/src/elements/elements.dart' |
| 12 show Element, ClassElement, LibraryElement; |
12 import 'package:compiler/src/universe/class_set.dart'; | 13 import 'package:compiler/src/universe/class_set.dart'; |
13 import 'package:compiler/src/world.dart' show ClosedWorld; | 14 import 'package:compiler/src/world.dart' show ClosedWorld; |
14 | 15 |
15 void main() { | 16 void main() { |
16 asyncTest(() async { | 17 asyncTest(() async { |
17 await testClassSets(); | 18 await testClassSets(); |
18 await testProperties(); | 19 await testProperties(); |
| 20 await testNativeClasses(); |
19 }); | 21 }); |
20 } | 22 } |
21 | 23 |
22 testClassSets() async { | 24 testClassSets() async { |
23 var env = await TypeEnvironment.create( | 25 var env = await TypeEnvironment.create( |
24 r""" | 26 r""" |
25 class A implements X {} | 27 class A implements X {} |
26 class B {} | 28 class B {} |
27 class C_Super extends A {} | 29 class C_Super extends A {} |
28 class C extends C_Super {} | 30 class C extends C_Super {} |
29 class D implements A {} | 31 class D implements A {} |
30 class E extends B implements A {} | 32 class E extends B implements A {} |
31 class F extends Object with A implements B {} | 33 class F extends Object with A implements B {} |
32 class G extends Object with A, B {} | 34 class G extends Object with A, B {} |
33 class X {} | 35 class X {} |
34 """, | 36 """, |
35 mainSource: r""" | 37 mainSource: r""" |
| 38 import 'dart:html' as html; |
36 main() { | 39 main() { |
37 new A(); | 40 new A(); |
38 new B(); | 41 new B(); |
39 new C(); | 42 new C(); |
40 new D(); | 43 new D(); |
41 new E(); | 44 new E(); |
42 new F(); | 45 new F(); |
43 new G(); | 46 new G(); |
| 47 html.window; |
| 48 new html.Worker(''); |
44 } | 49 } |
45 """, | 50 """, |
46 useMockCompiler: false); | 51 useMockCompiler: false); |
47 ClosedWorld closedWorld = env.compiler.closedWorld; | 52 ClosedWorld closedWorld = env.compiler.closedWorld; |
48 | 53 |
49 ClassElement Object_ = env.getElement("Object"); | 54 ClassElement Object_ = env.getElement("Object"); |
50 ClassElement A = env.getElement("A"); | 55 ClassElement A = env.getElement("A"); |
51 ClassElement B = env.getElement("B"); | 56 ClassElement B = env.getElement("B"); |
52 ClassElement C = env.getElement("C"); | 57 ClassElement C = env.getElement("C"); |
53 ClassElement D = env.getElement("D"); | 58 ClassElement D = env.getElement("D"); |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 check("G3", hasStrictSubtype: false, hasOnlySubclasses: true); | 296 check("G3", hasStrictSubtype: false, hasOnlySubclasses: true); |
292 check("G4", hasStrictSubtype: false, hasOnlySubclasses: true); | 297 check("G4", hasStrictSubtype: false, hasOnlySubclasses: true); |
293 | 298 |
294 // class H4 extends H2 with H extends H1 extends H instantiated | 299 // class H4 extends H2 with H extends H1 extends H instantiated |
295 check("H", hasStrictSubtype: true, hasOnlySubclasses: true); | 300 check("H", hasStrictSubtype: true, hasOnlySubclasses: true); |
296 check("H1", hasStrictSubtype: true, hasOnlySubclasses: true); | 301 check("H1", hasStrictSubtype: true, hasOnlySubclasses: true); |
297 check("H2", hasStrictSubtype: true, hasOnlySubclasses: true); | 302 check("H2", hasStrictSubtype: true, hasOnlySubclasses: true); |
298 check("H3", hasStrictSubtype: false, hasOnlySubclasses: true); | 303 check("H3", hasStrictSubtype: false, hasOnlySubclasses: true); |
299 check("H4", hasStrictSubtype: false, hasOnlySubclasses: true); | 304 check("H4", hasStrictSubtype: false, hasOnlySubclasses: true); |
300 } | 305 } |
| 306 |
| 307 testNativeClasses() async { |
| 308 var env = await TypeEnvironment.create('', |
| 309 mainSource: r""" |
| 310 import 'dart:html' as html; |
| 311 main() { |
| 312 html.window; // Creates 'Window'. |
| 313 new html.Worker(''); // Creates 'Worker'. |
| 314 new html.CanvasElement() // Creates CanvasElement |
| 315 ..getContext(''); // Creates CanvasRenderingContext2D |
| 316 } |
| 317 """, |
| 318 useMockCompiler: false); |
| 319 ClosedWorld closedWorld = env.compiler.closedWorld; |
| 320 LibraryElement dart_html = |
| 321 env.compiler.libraryLoader.lookupLibrary(Uris.dart_html); |
| 322 |
| 323 ClassElement clsEventTarget = dart_html.findExported('EventTarget'); |
| 324 ClassElement clsWindow = dart_html.findExported('Window'); |
| 325 ClassElement clsAbstractWorker = dart_html.findExported('AbstractWorker'); |
| 326 ClassElement clsWorker = dart_html.findExported('Worker'); |
| 327 ClassElement clsCanvasElement = dart_html.findExported('CanvasElement'); |
| 328 ClassElement clsCanvasRenderingContext = |
| 329 dart_html.findExported('CanvasRenderingContext'); |
| 330 ClassElement clsCanvasRenderingContext2D = |
| 331 dart_html.findExported('CanvasRenderingContext2D'); |
| 332 |
| 333 List<ClassElement> allClasses = [ |
| 334 clsEventTarget, |
| 335 clsWindow, |
| 336 clsAbstractWorker, |
| 337 clsWorker, |
| 338 clsCanvasElement, |
| 339 clsCanvasRenderingContext, |
| 340 clsCanvasRenderingContext2D |
| 341 ]; |
| 342 |
| 343 check(ClassElement cls, |
| 344 {bool isDirectlyInstantiated, |
| 345 bool isAbstractlyInstantiated, |
| 346 bool isIndirectlyInstantiated, |
| 347 bool hasStrictSubtype, |
| 348 bool hasOnlySubclasses, |
| 349 ClassElement lubOfInstantiatedSubclasses, |
| 350 ClassElement lubOfInstantiatedSubtypes, |
| 351 int instantiatedSubclassCount, |
| 352 int instantiatedSubtypeCount, |
| 353 List<ClassElement> subclasses: const <ClassElement>[], |
| 354 List<ClassElement> subtypes: const <ClassElement>[]}) { |
| 355 ClassSet classSet = closedWorld.getClassSet(cls); |
| 356 ClassHierarchyNode node = classSet.node; |
| 357 |
| 358 String dumpText = '\n${closedWorld.dump(cls)}'; |
| 359 |
| 360 Expect.equals( |
| 361 isDirectlyInstantiated, |
| 362 closedWorld.isDirectlyInstantiated(cls), |
| 363 "Unexpected isDirectlyInstantiated property on $cls.$dumpText"); |
| 364 Expect.equals( |
| 365 isAbstractlyInstantiated, |
| 366 closedWorld.isAbstractlyInstantiated(cls), |
| 367 "Unexpected isAbstractlyInstantiated property on $cls.$dumpText"); |
| 368 Expect.equals( |
| 369 isIndirectlyInstantiated, |
| 370 closedWorld.isIndirectlyInstantiated(cls), |
| 371 "Unexpected isIndirectlyInstantiated property on $cls.$dumpText"); |
| 372 Expect.equals(hasStrictSubtype, closedWorld.hasAnyStrictSubtype(cls), |
| 373 "Unexpected hasAnyStrictSubtype property on $cls.$dumpText"); |
| 374 Expect.equals(hasOnlySubclasses, closedWorld.hasOnlySubclasses(cls), |
| 375 "Unexpected hasOnlySubclasses property on $cls.$dumpText"); |
| 376 Expect.equals( |
| 377 lubOfInstantiatedSubclasses, |
| 378 node.getLubOfInstantiatedSubclasses(), |
| 379 "Unexpected getLubOfInstantiatedSubclasses() result on $cls.$dumpText"); |
| 380 Expect.equals( |
| 381 lubOfInstantiatedSubtypes, |
| 382 classSet.getLubOfInstantiatedSubtypes(), |
| 383 "Unexpected getLubOfInstantiatedSubtypes() result on $cls.$dumpText"); |
| 384 if (instantiatedSubclassCount != null) { |
| 385 Expect.equals(instantiatedSubclassCount, node.instantiatedSubclassCount, |
| 386 "Unexpected instantiatedSubclassCount property on $cls.$dumpText"); |
| 387 } |
| 388 if (instantiatedSubtypeCount != null) { |
| 389 Expect.equals(instantiatedSubtypeCount, classSet.instantiatedSubtypeCount, |
| 390 "Unexpected instantiatedSubtypeCount property on $cls.$dumpText"); |
| 391 } |
| 392 for (ClassElement other in allClasses) { |
| 393 if (other == cls) continue; |
| 394 if (!closedWorld.isExplicitlyInstantiated(other)) continue; |
| 395 Expect.equals( |
| 396 subclasses.contains(other), |
| 397 closedWorld.isSubclassOf(other, cls), |
| 398 "Unexpected subclass relation between $other and $cls."); |
| 399 Expect.equals( |
| 400 subtypes.contains(other), |
| 401 closedWorld.isSubtypeOf(other, cls), |
| 402 "Unexpected subtype relation between $other and $cls."); |
| 403 } |
| 404 |
| 405 Set<ClassElement> strictSubclasses = new Set<ClassElement>(); |
| 406 closedWorld.forEachStrictSubclassOf(cls, (ClassElement other) { |
| 407 if (allClasses.contains(other)) { |
| 408 strictSubclasses.add(other); |
| 409 } |
| 410 }); |
| 411 Expect.setEquals(subclasses, strictSubclasses, |
| 412 "Unexpected strict subclasses of $cls: ${strictSubclasses}."); |
| 413 |
| 414 Set<ClassElement> strictSubtypes = new Set<ClassElement>(); |
| 415 closedWorld.forEachStrictSubtypeOf(cls, (ClassElement other) { |
| 416 if (allClasses.contains(other)) { |
| 417 strictSubtypes.add(other); |
| 418 } |
| 419 }); |
| 420 Expect.setEquals(subtypes, strictSubtypes, |
| 421 "Unexpected strict subtypes of $cls: $strictSubtypes."); |
| 422 } |
| 423 |
| 424 // Extended by Window. |
| 425 check(clsEventTarget, |
| 426 isDirectlyInstantiated: false, |
| 427 isAbstractlyInstantiated: false, |
| 428 isIndirectlyInstantiated: true, |
| 429 hasStrictSubtype: true, |
| 430 hasOnlySubclasses: true, |
| 431 lubOfInstantiatedSubclasses: clsEventTarget, |
| 432 lubOfInstantiatedSubtypes: clsEventTarget, |
| 433 // May vary with implementation, do no test. |
| 434 instantiatedSubclassCount: null, |
| 435 instantiatedSubtypeCount: null, |
| 436 subclasses: [clsWindow, clsCanvasElement, clsWorker], |
| 437 subtypes: [clsWindow, clsCanvasElement, clsWorker]); |
| 438 |
| 439 // Created by 'html.window'. |
| 440 check(clsWindow, |
| 441 isDirectlyInstantiated: false, |
| 442 isAbstractlyInstantiated: true, |
| 443 isIndirectlyInstantiated: false, |
| 444 hasStrictSubtype: false, |
| 445 hasOnlySubclasses: true, |
| 446 lubOfInstantiatedSubclasses: clsWindow, |
| 447 lubOfInstantiatedSubtypes: clsWindow, |
| 448 instantiatedSubclassCount: 0, |
| 449 instantiatedSubtypeCount: 0); |
| 450 |
| 451 // Implemented by 'Worker'. |
| 452 check(clsAbstractWorker, |
| 453 isDirectlyInstantiated: false, |
| 454 isAbstractlyInstantiated: false, |
| 455 isIndirectlyInstantiated: false, |
| 456 hasStrictSubtype: true, |
| 457 hasOnlySubclasses: false, |
| 458 lubOfInstantiatedSubclasses: null, |
| 459 lubOfInstantiatedSubtypes: clsWorker, |
| 460 instantiatedSubclassCount: 0, |
| 461 instantiatedSubtypeCount: 1, |
| 462 subtypes: [clsWorker]); |
| 463 |
| 464 // Created by 'new html.Worker'. |
| 465 check(clsWorker, |
| 466 isDirectlyInstantiated: false, |
| 467 isAbstractlyInstantiated: true, |
| 468 isIndirectlyInstantiated: false, |
| 469 hasStrictSubtype: false, |
| 470 hasOnlySubclasses: true, |
| 471 lubOfInstantiatedSubclasses: clsWorker, |
| 472 lubOfInstantiatedSubtypes: clsWorker, |
| 473 instantiatedSubclassCount: 0, |
| 474 instantiatedSubtypeCount: 0); |
| 475 |
| 476 // Created by 'new html.CanvasElement'. |
| 477 check(clsCanvasElement, |
| 478 isDirectlyInstantiated: false, |
| 479 isAbstractlyInstantiated: true, |
| 480 isIndirectlyInstantiated: false, |
| 481 hasStrictSubtype: false, |
| 482 hasOnlySubclasses: true, |
| 483 lubOfInstantiatedSubclasses: clsCanvasElement, |
| 484 lubOfInstantiatedSubtypes: clsCanvasElement, |
| 485 instantiatedSubclassCount: 0, |
| 486 instantiatedSubtypeCount: 0); |
| 487 |
| 488 // Implemented by CanvasRenderingContext2D and RenderingContext. |
| 489 check(clsCanvasRenderingContext, |
| 490 isDirectlyInstantiated: false, |
| 491 isAbstractlyInstantiated: false, |
| 492 isIndirectlyInstantiated: false, |
| 493 hasStrictSubtype: true, |
| 494 hasOnlySubclasses: false, |
| 495 lubOfInstantiatedSubclasses: null, |
| 496 lubOfInstantiatedSubtypes: clsCanvasRenderingContext, |
| 497 instantiatedSubclassCount: 0, |
| 498 instantiatedSubtypeCount: 2, |
| 499 subtypes: [clsCanvasRenderingContext2D]); |
| 500 |
| 501 // Created by 'html.CanvasElement.getContext'. |
| 502 check(clsCanvasRenderingContext2D, |
| 503 isDirectlyInstantiated: false, |
| 504 isAbstractlyInstantiated: true, |
| 505 isIndirectlyInstantiated: false, |
| 506 hasStrictSubtype: false, |
| 507 hasOnlySubclasses: true, |
| 508 lubOfInstantiatedSubclasses: clsCanvasRenderingContext2D, |
| 509 lubOfInstantiatedSubtypes: clsCanvasRenderingContext2D, |
| 510 instantiatedSubclassCount: 0, |
| 511 instantiatedSubtypeCount: 0); |
| 512 } |
OLD | NEW |