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

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: Removed obsolete function. 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..78d99d24956ba7b7e54aee4b5e7d7989378335fc 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,16 @@ $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);
}
-
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 +839,19 @@ $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]) {
+ if (check == compiler.dynamicClass) {
+ continue;
+ }
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');
kasperl 2013/01/29 15:02:34 Isn't it a little bit dangerous to manipulate (add
karlklose 2013/01/30 12:01:19 I am using the name as returned by the namer, the
+ }
};
}
}
@@ -1195,11 +1206,15 @@ $lazyInitializerLogic
* super class because they will be inherited at runtime.
*/
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)) {
+ 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 +1228,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 +1245,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 +1256,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 +1271,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