Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart |
| diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart |
| index 564b457e240a376109ba9414587b257b838346dc..24764561fd5baf750f8b46132470a191ce3617c4 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart |
| @@ -4,11 +4,21 @@ |
| part of js_backend; |
| +/// For each class, stores the possible class subtype tests that could succeed. |
| +abstract class TypeChecks implements Iterable<ClassElement> { |
| + /// Get the set of checks required for class [element]. |
| + Iterable<ClassElement> operator[](ClassElement element); |
| +} |
| + |
| class RuntimeTypeInformation { |
| final Compiler compiler; |
| RuntimeTypeInformation(this.compiler); |
| + /// Contains the classes of all arguments that have been used in |
| + /// instantiations and checks. |
| + Set<ClassElement> allArguments; |
| + |
| bool isJsNative(Element element) { |
| return (element == compiler.intClass || |
| element == compiler.boolClass || |
| @@ -20,6 +30,60 @@ class RuntimeTypeInformation { |
| element == compiler.dynamicClass); |
| } |
| + TypeChecks computeRequiredChecks() { |
| + Set<ClassElement> instantiatedArguments = new Set<ClassElement>(); |
| + for (DartType type in compiler.codegenWorld.instantiatedTypes) { |
| + addAllInterfaceTypeArguments(type, instantiatedArguments); |
| + } |
| + |
| + Set<ClassElement> checkedArguments = new Set<ClassElement>(); |
| + for (DartType type in compiler.enqueuer.codegen.universe.isChecks) { |
| + addAllInterfaceTypeArguments(type, checkedArguments); |
| + } |
| + |
| + allArguments = new Set<ClassElement>.from(instantiatedArguments) |
| + ..addAll(checkedArguments); |
|
kasperl
2012/12/13 09:48:55
I prefer 4 space indent of the .. lines.
karlklose
2012/12/13 12:55:46
Done.
|
| + |
| + TypeCheckMapping requiredChecks = new TypeCheckMapping(); |
| + for (ClassElement element in instantiatedArguments) { |
| + if (element == compiler.dynamicClass) continue; |
| + if (checkedArguments.contains(element)) { |
| + requiredChecks.add(element, element); |
| + } |
| + // Find all supertypes of [element] in [checkedArguments] and add checks. |
| + for (DartType supertype in element.allSupertypes) { |
| + ClassElement superelement = supertype.element; |
| + if (checkedArguments.contains(superelement)) { |
| + requiredChecks.add(element, superelement); |
| + } |
| + } |
| + } |
| + |
| + return requiredChecks; |
| + } |
| + |
| + void addAllInterfaceTypeArguments(DartType type, Set<ClassElement> classes) { |
| + if (type is !InterfaceType) return; |
| + for (DartType argument in type.typeArguments) { |
| + forEachInterfaceType(argument, (InterfaceType t) { |
| + ClassElement cls = t.element; |
| + if (cls != compiler.dynamicClass && cls != compiler.objectClass) { |
| + classes.add(cls); |
| + } |
| + }); |
| + } |
| + } |
| + |
| + void forEachInterfaceType(DartType type, f(InterfaceType type)) { |
| + if (type.kind == TypeKind.INTERFACE) { |
| + f(type); |
| + InterfaceType interface = type; |
| + for (DartType argument in interface.typeArguments) { |
| + forEachInterfaceType(argument, f); |
| + } |
| + } |
| + } |
| + |
| /// Return the unique name for the element as an unquoted string. |
| String getNameAsString(Element element) { |
| JavaScriptBackend backend = compiler.backend; |
| @@ -31,20 +95,7 @@ class RuntimeTypeInformation { |
| String getJsName(Element element) { |
| JavaScriptBackend backend = compiler.backend; |
| Namer namer = backend.namer; |
| - if (element.isClass()) { |
| - ClassElement cls = element; |
| - // If the class is not instantiated, we will not generate code for it and |
| - // thus cannot refer to its constructor. For now, use a string instead of |
| - // a reference to the constructor. |
| - // TODO(karlklose): remove this and record classes that we need only |
| - // for runtime types and emit structures for them. |
| - Universe universe = compiler.enqueuer.resolution.universe; |
| - if (!universe.instantiatedClasses.contains(cls)) { |
| - return "'${namer.isolateAccess(element)}'"; |
| - } |
| - } |
| - return isJsNative(element) ? "'${element.name.slowToString()}'" |
| - : namer.isolateAccess(element); |
| + return namer.isolateAccess(element); |
| } |
| String getRawTypeRepresentation(DartType type) { |
| @@ -101,3 +152,20 @@ class RuntimeTypeInformation { |
| } |
| } |
| } |
| + |
| +class TypeCheckMapping implements TypeChecks { |
| + final Map<ClassElement, Set<ClassElement>> map = |
| + new Map<ClassElement, Set<ClassElement>>(); |
| + |
| + Iterable<ClassElement> operator[](ClassElement element) { |
| + Set<ClassElement> result = map[element]; |
| + return result != null ? result : const <ClassElement>[]; |
| + } |
| + |
| + void add(ClassElement cls, ClassElement check) { |
| + map.putIfAbsent(cls, () => new Set<ClassElement>()); |
| + map[cls].add(check); |
| + } |
| + |
| + Iterator<ClassElement> iterator() => map.keys.iterator(); |
| +} |