Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Unified Diff: sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart

Issue 11557010: Implement subtype checks on type arguments. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Update test expectations. Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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();
+}

Powered by Google App Engine
This is Rietveld 408576698