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

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

Issue 12018015: Implement substitution for type variables. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address Nicolas' comments. Created 7 years, 11 months 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/emitter.dart
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
index 44577dc9e2afd94aebf9475424d8e55da806b078..0d0f27881b43ecb21e2e2c17fc132b95dcf75478 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
@@ -763,7 +763,7 @@ $lazyInitializerLogic
includeBackendMembers: true,
includeSuperMembers: false);
- generateIsTestsOn(classElement, (Element other) {
+ void generateIsTest(Element other) {
js.Expression code;
if (compiler.objectClass == other) return;
if (nativeEmitter.requiresNativeIsCheck(other)) {
@@ -772,7 +772,22 @@ $lazyInitializerLogic
code = new js.LiteralBool(true);
}
builder.addProperty(namer.operatorIs(other), code);
- });
+ }
+
+ void generateSubstitution(Element other) {
+ RuntimeTypeInformation rti = backend.rti;
+ // TODO(karlklose): support typedefs with variables.
+ if (other.kind == ElementKind.CLASS) {
+ String substitution = rti.getSupertypeSubstitution(classElement, other,
+ alwaysGenerateFunction: true);
+ if (substitution != null) {
+ builder.addProperty(namer.substitutionName(other),
+ new js.LiteralExpression(substitution));
+ }
+ }
+ }
+
+ generateIsTestsOn(classElement, generateIsTest, generateSubstitution);
if (identical(classElement, compiler.objectClass)
&& compiler.enabledNoSuchMethod) {
@@ -805,23 +820,24 @@ $lazyInitializerLogic
void emitRuntimeClassesAndTests(CodeBuffer buffer) {
JavaScriptBackend backend = compiler.backend;
RuntimeTypeInformation rti = backend.rti;
-
- TypeChecks typeChecks = rti.computeRequiredChecks();
+ TypeChecks typeChecks = rti.getRequiredChecks();
bool needsHolder(ClassElement cls) {
return !neededClasses.contains(cls) || cls.isNative() ||
rti.isJsNative(cls);
}
+ /**
+ * Generates a holder object if it is needed. A holder is a JavaScript
+ * object literal with a field [builtin$cls] that contains the name of the
+ * class as a string (just like object constructors do). The is-checkes
ngeoffray 2013/01/31 08:28:08 checkes -> checks
karlklose 2013/02/01 07:36:36 Done.
+ * for the class are are added to the holder object later.
+ */
void maybeGenerateHolder(ClassElement cls) {
if (!needsHolder(cls)) return;
-
String holder = namer.isolateAccess(cls);
String name = namer.getName(cls);
buffer.add("$holder$_=$_{builtin\$cls:$_'$name'");
- for (ClassElement check in typeChecks[cls]) {
- buffer.add(',$_${namer.operatorIs(check)}:${_}true');
- };
buffer.add('}$N');
}
@@ -831,16 +847,16 @@ $lazyInitializerLogic
maybeGenerateHolder(cls);
}
- // Add checks to the constructors of instantiated classes.
+ // Add checks to the constructors of instantiated classes or to the created
+ // holder object.
for (ClassElement cls in typeChecks) {
- if (needsHolder(cls)) {
- // We already emitted the is-checks in the object definition for this
- // class.
- continue;
- }
String holder = namer.isolateAccess(cls);
for (ClassElement check in typeChecks[cls]) {
buffer.add('$holder.${namer.operatorIs(check)}$_=${_}true$N');
+ String body = rti.getSupertypeSubstitution(cls, check);
+ if (body != null) {
+ buffer.add('$holder.${namer.substitutionName(check)}$_=${_}$body$N');
+ }
};
}
}
@@ -1191,15 +1207,22 @@ $lazyInitializerLogic
/**
* Generate "is tests" for [cls]: itself, and the "is tests" for the
- * classes it implements. We don't need to add the "is tests" of the
- * super class because they will be inherited at runtime.
+ * classes it implements and type argument substitution functions for these
+ * tests. We don't need to add the "is tests" of the super class because
+ * they will be inherited at runtime, but we need to generate the substitution,
ngeoffray 2013/01/31 08:28:08 line too long
karlklose 2013/02/01 07:36:36 Done.
+ * because it may have changed.
ngeoffray 2013/01/31 08:28:08 Please provide an example.
karlklose 2013/02/01 07:36:36 Done.
*/
void generateIsTestsOn(ClassElement cls,
- void emitIsTest(Element element)) {
+ void emitIsTest(Element element),
+ void emitSubstitution(Element element)) {
if (checkedClasses.contains(cls)) {
emitIsTest(cls);
+ emitSubstitution(cls);
+ }
+ if (cls.superclass != null && checkedClasses.contains(cls.superclass)) {
+ // TODO(karlklose): do not regenerate it, if it has not changed.
+ emitSubstitution(cls.superclass);
}
-
Set<Element> generated = new Set<Element>();
// A class that defines a [:call:] method implicitly implements
// [Function] and needs checks for all typedefs that are used in is-checks.
@@ -1213,13 +1236,15 @@ $lazyInitializerLogic
if (call != null) {
generateInterfacesIsTests(compiler.functionClass,
emitIsTest,
+ emitSubstitution,
generated);
getTypedefChecksOn(call.computeType(compiler)).forEach(emitIsTest);
}
}
for (DartType interfaceType in cls.interfaces) {
- generateInterfacesIsTests(interfaceType.element, emitIsTest, generated);
+ generateInterfacesIsTests(interfaceType.element, emitIsTest,
+ emitSubstitution, generated);
}
// For native classes, we also have to run through their mixin
@@ -1228,7 +1253,8 @@ $lazyInitializerLogic
visitNativeMixins(cls, (MixinApplicationElement mixin) {
for (DartType interfaceType in mixin.interfaces) {
ClassElement interfaceElement = interfaceType.element;
- generateInterfacesIsTests(interfaceType.element, emitIsTest, generated);
+ generateInterfacesIsTests(interfaceType.element, emitIsTest,
+ emitSubstitution, generated);
}
});
}
@@ -1238,11 +1264,13 @@ $lazyInitializerLogic
*/
void generateInterfacesIsTests(ClassElement cls,
void emitIsTest(ClassElement element),
+ void emitSubstitution(ClassElement element),
Set<Element> alreadyGenerated) {
- void tryEmitTest(ClassElement cls) {
- if (!alreadyGenerated.contains(cls) && checkedClasses.contains(cls)) {
- alreadyGenerated.add(cls);
- emitIsTest(cls);
+ void tryEmitTest(ClassElement check) {
+ if (!alreadyGenerated.contains(check) && checkedClasses.contains(check)) {
+ alreadyGenerated.add(check);
+ emitIsTest(check);
+ emitSubstitution(check);
}
};
@@ -1251,14 +1279,16 @@ $lazyInitializerLogic
for (DartType interfaceType in cls.interfaces) {
Element element = interfaceType.element;
tryEmitTest(element);
- generateInterfacesIsTests(element, emitIsTest, alreadyGenerated);
+ generateInterfacesIsTests(element, emitIsTest, emitSubstitution,
+ alreadyGenerated);
}
// We need to also emit "is checks" for the superclass and its supertypes.
ClassElement superclass = cls.superclass;
if (superclass != null) {
tryEmitTest(superclass);
- generateInterfacesIsTests(superclass, emitIsTest, alreadyGenerated);
+ generateInterfacesIsTests(superclass, emitIsTest, emitSubstitution,
+ alreadyGenerated);
}
}

Powered by Google App Engine
This is Rietveld 408576698