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..8375de7a45a83fb0776b784f391b7a41984b2aa7 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart |
| @@ -4,10 +4,20 @@ |
| part of js_backend; |
| +abstract class TypeChecks implements Iterable<ClassElement> { |
|
ngeoffray
2012/12/12 12:09:11
Please add a high-level comment on what this is, a
karlklose
2012/12/12 14:50:47
Done.
|
| + /// Get the set of checks required for class [element]. |
| + Set<ClassElement> operator[](ClassElement element); |
|
kasperl
2012/12/12 12:09:45
Does this have to be a set? Would an iterable be e
karlklose
2012/12/12 14:50:47
Done.
|
| +} |
| + |
| class RuntimeTypeInformation { |
| final Compiler compiler; |
| - RuntimeTypeInformation(this.compiler); |
| + /// Classes that are not instantiated but appear in type arguments and thus |
| + /// need a representation in JavaScript. |
| + final Set<ClassElement> requiredClasses; |
|
ngeoffray
2012/12/12 12:09:11
I would rename this field to make it more obvious
karlklose
2012/12/12 14:50:47
I have removed this set.
|
| + |
| + RuntimeTypeInformation(this.compiler) |
| + : requiredClasses = new Set<ClassElement>(); |
|
kasperl
2012/12/12 12:09:45
Move to declaration of requiredClasses.
karlklose
2012/12/12 14:50:47
I have removed this set.
|
| bool isJsNative(Element element) { |
| return (element == compiler.intClass || |
| @@ -20,6 +30,72 @@ class RuntimeTypeInformation { |
| element == compiler.dynamicClass); |
| } |
| + void referencedClass(ClassElement cls) { |
|
ngeoffray
2012/12/12 12:09:11
I would change this method to return whether the c
kasperl
2012/12/12 12:09:45
Maybe addReferencedClass? markClassAsReferenced? r
karlklose
2012/12/12 14:50:47
I have removed this method.
|
| + Universe universe = compiler.enqueuer.resolution.universe; |
| + if (!universe.instantiatedClasses.contains(cls) || |
|
kasperl
2012/12/12 12:09:45
It's not completely obvious from this code that th
karlklose
2012/12/12 14:50:47
I changed the CL to actually check against the nee
|
| + isJsNative(cls) || |
| + cls.isNative()) { |
| + // If the class is not instantiated or native, we will not generate code |
| + // for it and thus cannot refer to its constructor. Add the class to a |
| + // list of classes for which we need to generate a holder for the |
|
ngeoffray
2012/12/12 12:09:11
What will the holder be? How can it be referenced
karlklose
2012/12/12 14:50:47
I have removed this method. The holder is describe
|
| + // is-checks and the name field. |
| + requiredClasses.add(cls); |
| + } |
| + } |
| + |
| + 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); |
| + } |
| + |
| + 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) { |
| + referencedClass(cls); |
| + classes.add(cls); |
| + } |
| + }); |
| + } |
| + } |
| + |
| + void forEachInterfaceType(DartType type, f(InterfaceType type)) { |
| + if (type.kind == TypeKind.INTERFACE) { |
| + if (f != null) f(type); |
|
kasperl
2012/12/12 12:09:45
Why would you call this with f == null? Nothing wo
karlklose
2012/12/12 14:50:47
Removed.
(This function originally took two callb
|
| + 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 +107,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 +164,21 @@ class RuntimeTypeInformation { |
| } |
| } |
| } |
| + |
| +class TypeCheckMapping implements TypeChecks { |
| + Map<ClassElement, Set<ClassElement>> map; |
|
kasperl
2012/12/12 12:09:45
final?
karlklose
2012/12/12 14:50:47
Done.
|
| + |
| + TypeCheckMapping() : map = new Map<ClassElement, Set<ClassElement>>(); |
|
kasperl
2012/12/12 12:09:45
Initialize at declaration.
karlklose
2012/12/12 14:50:47
Done.
|
| + |
| + Set<ClassElement> operator[](ClassElement element) { |
| + Set<ClassElement> result = map[element]; |
| + return result != null ? result : new Set<ClassElement>(); |
|
kasperl
2012/12/12 12:09:45
Seems a bit expensive to return a new empty set ev
karlklose
2012/12/12 14:50:47
Done.
|
| + } |
| + |
| + void add(ClassElement cls, ClassElement check) { |
| + map.putIfAbsent(cls, () => new Set<ClassElement>()); |
| + map[cls].add(check); |
| + } |
| + |
| + Iterator<ClassElement> iterator() => map.keys.iterator(); |
| +} |