Index: tests/compiler/dart2js/world_test.dart |
diff --git a/tests/compiler/dart2js/world_test.dart b/tests/compiler/dart2js/world_test.dart |
index c68e05a268a00090745c5cf77b6166ece28e1ef2..4e293077f43454f922a4ad616430315ebdf53a20 100644 |
--- a/tests/compiler/dart2js/world_test.dart |
+++ b/tests/compiler/dart2js/world_test.dart |
@@ -7,8 +7,9 @@ library world_test; |
import 'package:expect/expect.dart'; |
import 'package:async_helper/async_helper.dart'; |
import 'type_test_helper.dart'; |
-import 'package:compiler/src/common.dart'; |
-import 'package:compiler/src/elements/elements.dart' show Element, ClassElement; |
+import 'package:compiler/src/common/names.dart'; |
+import 'package:compiler/src/elements/elements.dart' |
+ show Element, ClassElement, LibraryElement; |
import 'package:compiler/src/universe/class_set.dart'; |
import 'package:compiler/src/world.dart' show ClosedWorld; |
@@ -16,6 +17,7 @@ void main() { |
asyncTest(() async { |
await testClassSets(); |
await testProperties(); |
+ await testNativeClasses(); |
}); |
} |
@@ -33,6 +35,7 @@ testClassSets() async { |
class X {} |
""", |
mainSource: r""" |
+ import 'dart:html' as html; |
main() { |
new A(); |
new B(); |
@@ -41,6 +44,8 @@ testClassSets() async { |
new E(); |
new F(); |
new G(); |
+ html.window; |
+ new html.Worker(''); |
} |
""", |
useMockCompiler: false); |
@@ -298,3 +303,210 @@ testProperties() async { |
check("H3", hasStrictSubtype: false, hasOnlySubclasses: true); |
check("H4", hasStrictSubtype: false, hasOnlySubclasses: true); |
} |
+ |
+testNativeClasses() async { |
+ var env = await TypeEnvironment.create('', |
+ mainSource: r""" |
+ import 'dart:html' as html; |
+ main() { |
+ html.window; // Creates 'Window'. |
+ new html.Worker(''); // Creates 'Worker'. |
+ new html.CanvasElement() // Creates CanvasElement |
+ ..getContext(''); // Creates CanvasRenderingContext2D |
+ } |
+ """, |
+ useMockCompiler: false); |
+ ClosedWorld closedWorld = env.compiler.closedWorld; |
+ LibraryElement dart_html = |
+ env.compiler.libraryLoader.lookupLibrary(Uris.dart_html); |
+ |
+ ClassElement clsEventTarget = dart_html.findExported('EventTarget'); |
+ ClassElement clsWindow = dart_html.findExported('Window'); |
+ ClassElement clsAbstractWorker = dart_html.findExported('AbstractWorker'); |
+ ClassElement clsWorker = dart_html.findExported('Worker'); |
+ ClassElement clsCanvasElement = dart_html.findExported('CanvasElement'); |
+ ClassElement clsCanvasRenderingContext = |
+ dart_html.findExported('CanvasRenderingContext'); |
+ ClassElement clsCanvasRenderingContext2D = |
+ dart_html.findExported('CanvasRenderingContext2D'); |
+ |
+ List<ClassElement> allClasses = [ |
+ clsEventTarget, |
+ clsWindow, |
+ clsAbstractWorker, |
+ clsWorker, |
+ clsCanvasElement, |
+ clsCanvasRenderingContext, |
+ clsCanvasRenderingContext2D |
+ ]; |
+ |
+ check(ClassElement cls, |
+ {bool isDirectlyInstantiated, |
+ bool isAbstractlyInstantiated, |
+ bool isIndirectlyInstantiated, |
+ bool hasStrictSubtype, |
+ bool hasOnlySubclasses, |
+ ClassElement lubOfInstantiatedSubclasses, |
+ ClassElement lubOfInstantiatedSubtypes, |
+ int instantiatedSubclassCount, |
+ int instantiatedSubtypeCount, |
+ List<ClassElement> subclasses: const <ClassElement>[], |
+ List<ClassElement> subtypes: const <ClassElement>[]}) { |
+ ClassSet classSet = closedWorld.getClassSet(cls); |
+ ClassHierarchyNode node = classSet.node; |
+ |
+ String dumpText = '\n${closedWorld.dump(cls)}'; |
+ |
+ Expect.equals( |
+ isDirectlyInstantiated, |
+ closedWorld.isDirectlyInstantiated(cls), |
+ "Unexpected isDirectlyInstantiated property on $cls.$dumpText"); |
+ Expect.equals( |
+ isAbstractlyInstantiated, |
+ closedWorld.isAbstractlyInstantiated(cls), |
+ "Unexpected isAbstractlyInstantiated property on $cls.$dumpText"); |
+ Expect.equals( |
+ isIndirectlyInstantiated, |
+ closedWorld.isIndirectlyInstantiated(cls), |
+ "Unexpected isIndirectlyInstantiated property on $cls.$dumpText"); |
+ Expect.equals(hasStrictSubtype, closedWorld.hasAnyStrictSubtype(cls), |
+ "Unexpected hasAnyStrictSubtype property on $cls.$dumpText"); |
+ Expect.equals(hasOnlySubclasses, closedWorld.hasOnlySubclasses(cls), |
+ "Unexpected hasOnlySubclasses property on $cls.$dumpText"); |
+ Expect.equals( |
+ lubOfInstantiatedSubclasses, |
+ node.getLubOfInstantiatedSubclasses(), |
+ "Unexpected getLubOfInstantiatedSubclasses() result on $cls.$dumpText"); |
+ Expect.equals( |
+ lubOfInstantiatedSubtypes, |
+ classSet.getLubOfInstantiatedSubtypes(), |
+ "Unexpected getLubOfInstantiatedSubtypes() result on $cls.$dumpText"); |
+ if (instantiatedSubclassCount != null) { |
+ Expect.equals(instantiatedSubclassCount, node.instantiatedSubclassCount, |
+ "Unexpected instantiatedSubclassCount property on $cls.$dumpText"); |
+ } |
+ if (instantiatedSubtypeCount != null) { |
+ Expect.equals(instantiatedSubtypeCount, classSet.instantiatedSubtypeCount, |
+ "Unexpected instantiatedSubtypeCount property on $cls.$dumpText"); |
+ } |
+ for (ClassElement other in allClasses) { |
+ if (other == cls) continue; |
+ if (!closedWorld.isExplicitlyInstantiated(other)) continue; |
+ Expect.equals( |
+ subclasses.contains(other), |
+ closedWorld.isSubclassOf(other, cls), |
+ "Unexpected subclass relation between $other and $cls."); |
+ Expect.equals( |
+ subtypes.contains(other), |
+ closedWorld.isSubtypeOf(other, cls), |
+ "Unexpected subtype relation between $other and $cls."); |
+ } |
+ |
+ Set<ClassElement> strictSubclasses = new Set<ClassElement>(); |
+ closedWorld.forEachStrictSubclassOf(cls, (ClassElement other) { |
+ if (allClasses.contains(other)) { |
+ strictSubclasses.add(other); |
+ } |
+ }); |
+ Expect.setEquals(subclasses, strictSubclasses, |
+ "Unexpected strict subclasses of $cls: ${strictSubclasses}."); |
+ |
+ Set<ClassElement> strictSubtypes = new Set<ClassElement>(); |
+ closedWorld.forEachStrictSubtypeOf(cls, (ClassElement other) { |
+ if (allClasses.contains(other)) { |
+ strictSubtypes.add(other); |
+ } |
+ }); |
+ Expect.setEquals(subtypes, strictSubtypes, |
+ "Unexpected strict subtypes of $cls: $strictSubtypes."); |
+ } |
+ |
+ // Extended by Window. |
+ check(clsEventTarget, |
+ isDirectlyInstantiated: false, |
+ isAbstractlyInstantiated: false, |
+ isIndirectlyInstantiated: true, |
+ hasStrictSubtype: true, |
+ hasOnlySubclasses: true, |
+ lubOfInstantiatedSubclasses: clsEventTarget, |
+ lubOfInstantiatedSubtypes: clsEventTarget, |
+ // May vary with implementation, do no test. |
+ instantiatedSubclassCount: null, |
+ instantiatedSubtypeCount: null, |
+ subclasses: [clsWindow, clsCanvasElement, clsWorker], |
+ subtypes: [clsWindow, clsCanvasElement, clsWorker]); |
+ |
+ // Created by 'html.window'. |
+ check(clsWindow, |
+ isDirectlyInstantiated: false, |
+ isAbstractlyInstantiated: true, |
+ isIndirectlyInstantiated: false, |
+ hasStrictSubtype: false, |
+ hasOnlySubclasses: true, |
+ lubOfInstantiatedSubclasses: clsWindow, |
+ lubOfInstantiatedSubtypes: clsWindow, |
+ instantiatedSubclassCount: 0, |
+ instantiatedSubtypeCount: 0); |
+ |
+ // Implemented by 'Worker'. |
+ check(clsAbstractWorker, |
+ isDirectlyInstantiated: false, |
+ isAbstractlyInstantiated: false, |
+ isIndirectlyInstantiated: false, |
+ hasStrictSubtype: true, |
+ hasOnlySubclasses: false, |
+ lubOfInstantiatedSubclasses: null, |
+ lubOfInstantiatedSubtypes: clsWorker, |
+ instantiatedSubclassCount: 0, |
+ instantiatedSubtypeCount: 1, |
+ subtypes: [clsWorker]); |
+ |
+ // Created by 'new html.Worker'. |
+ check(clsWorker, |
+ isDirectlyInstantiated: false, |
+ isAbstractlyInstantiated: true, |
+ isIndirectlyInstantiated: false, |
+ hasStrictSubtype: false, |
+ hasOnlySubclasses: true, |
+ lubOfInstantiatedSubclasses: clsWorker, |
+ lubOfInstantiatedSubtypes: clsWorker, |
+ instantiatedSubclassCount: 0, |
+ instantiatedSubtypeCount: 0); |
+ |
+ // Created by 'new html.CanvasElement'. |
+ check(clsCanvasElement, |
+ isDirectlyInstantiated: false, |
+ isAbstractlyInstantiated: true, |
+ isIndirectlyInstantiated: false, |
+ hasStrictSubtype: false, |
+ hasOnlySubclasses: true, |
+ lubOfInstantiatedSubclasses: clsCanvasElement, |
+ lubOfInstantiatedSubtypes: clsCanvasElement, |
+ instantiatedSubclassCount: 0, |
+ instantiatedSubtypeCount: 0); |
+ |
+ // Implemented by CanvasRenderingContext2D and RenderingContext. |
+ check(clsCanvasRenderingContext, |
+ isDirectlyInstantiated: false, |
+ isAbstractlyInstantiated: false, |
+ isIndirectlyInstantiated: false, |
+ hasStrictSubtype: true, |
+ hasOnlySubclasses: false, |
+ lubOfInstantiatedSubclasses: null, |
+ lubOfInstantiatedSubtypes: clsCanvasRenderingContext, |
+ instantiatedSubclassCount: 0, |
+ instantiatedSubtypeCount: 2, |
+ subtypes: [clsCanvasRenderingContext2D]); |
+ |
+ // Created by 'html.CanvasElement.getContext'. |
+ check(clsCanvasRenderingContext2D, |
+ isDirectlyInstantiated: false, |
+ isAbstractlyInstantiated: true, |
+ isIndirectlyInstantiated: false, |
+ hasStrictSubtype: false, |
+ hasOnlySubclasses: true, |
+ lubOfInstantiatedSubclasses: clsCanvasRenderingContext2D, |
+ lubOfInstantiatedSubtypes: clsCanvasRenderingContext2D, |
+ instantiatedSubclassCount: 0, |
+ instantiatedSubtypeCount: 0); |
+} |