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

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

Issue 12051056: Allow native classes to mixin behavior from an ordinary Dart class. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add 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 07fc08d3836c875a644cbf766d3a7902ff002647..77cce05652a474ca086fb61cbec269537da1f545 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
@@ -735,14 +735,38 @@ $lazyInitializerLogic
return;
}
+ void visitMember(ClassElement enclosing, Element member) {
+ assert(invariant(classElement, member.isDeclaration));
+ if (member.isInstanceMember()) {
+ addInstanceMember(member, builder);
+ }
+ }
+
+ // TODO(kasperl): We should make sure to only emit one version of
+ // overridden methods. Right now, we rely on the ordering so the
+ // methods pulled in from mixins are replaced with the members
+ // from the class definition, but it is broken if you a chain of
+ // mixin applications.
+
+ // If the class is a native class, we have to add the instance
+ // members defined in the non-native mixin applications used by
+ // the class.
+ if (classElement.isNative()) {
+ ClassElement superclass = classElement.superclass;
+ while (superclass.isMixinApplication) {
+ assert(!superclass.isNative());
+ superclass.forEachMember(
+ visitMember,
+ includeBackendMembers: true,
+ includeSuperMembers: false);
+ superclass = superclass.superclass;
+ }
+ }
+
classElement.implementation.forEachMember(
- (ClassElement enclosing, Element member) {
- assert(invariant(classElement, member.isDeclaration));
- if (member.isInstanceMember()) {
- addInstanceMember(member, builder);
- }
- },
- includeBackendMembers: true);
+ visitMember,
+ includeBackendMembers: true,
+ includeSuperMembers: false);
generateIsTestsOn(classElement, (Element other) {
js.Expression code;
@@ -891,6 +915,26 @@ $lazyInitializerLogic
}
}
+ // TODO(kasperl): We should make sure to only emit one version of
+ // overridden fields. Right now, we rely on the ordering so the
+ // fields pulled in from mixins are replaced with the fields from
+ // the class definition, but it is broken if you a chain of mixin
+ // applications.
+
+ // If the class is a native class, we have to add the fields
+ // defined in the non-native mixin applications used by the class.
+ if (classElement.isNative()) {
+ ClassElement superclass = classElement.superclass;
+ while (superclass.isMixinApplication) {
+ assert(!superclass.isNative());
+ superclass.forEachInstanceField(
+ visitField,
+ includeBackendMembers: true,
+ includeSuperMembers: false);
+ superclass = superclass.superclass;
+ }
+ }
+
// If a class is not instantiated then we add the field just so we can
// generate the field getter/setter dynamically. Since this is only
// allowed on fields that are in [classElement] we don't need to visit
@@ -1068,7 +1112,13 @@ $lazyInitializerLogic
needsDefineClass = true;
String className = namer.getName(classElement);
+
+ // Find the first non-native superclass.
ClassElement superclass = classElement.superclass;
+ while (superclass != null && superclass.isNative()) {
+ superclass = superclass.superclass;
+ }
+
String superName = "";
if (superclass != null) {
superName = namer.getName(superclass);
@@ -1163,8 +1213,25 @@ $lazyInitializerLogic
}
}
for (DartType interfaceType in cls.interfaces) {
- generateInterfacesIsTests(interfaceType.element, emitIsTest, generated);
+ ClassElement interfaceElement = interfaceType.element;
+ generateInterfacesIsTests(interfaceElement, emitIsTest, generated);
+ }
+
+ // For native classes, we also have to run through their
+ // non-native mixin applications and make sure we deal with 'is'
+ // tests correctly for those.
+ if (cls.isNative()) {
+ ClassElement superclass = cls.superclass;
+ while (superclass != null && superclass.isMixinApplication) {
+ assert(!superclass.isNative());
+ for (DartType interfaceType in superclass.interfaces) {
+ ClassElement interfaceElement = interfaceType.element;
+ generateInterfacesIsTests(interfaceElement, emitIsTest, generated);
+ }
+ superclass = superclass.superclass;
+ }
}
+
}
/**

Powered by Google App Engine
This is Rietveld 408576698