Index: pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart |
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart |
index 7dc3001e4f4389f77fd3eeca1f226347818b4d9a..4957d489266759a8a94b353eb02afddc905d0e68 100644 |
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart |
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart |
@@ -822,8 +822,10 @@ class FragmentEmitter { |
/// In this section prototype chains are updated and mixin functions are |
/// copied. |
js.Statement emitInheritance(Fragment fragment) { |
- List<js.Expression> inheritCalls = <js.Expression>[]; |
- List<js.Expression> mixinCalls = <js.Expression>[]; |
+ List<js.Statement> inheritCalls = <js.Statement>[]; |
+ List<js.Statement> mixinCalls = <js.Statement>[]; |
+ |
+ Map<Class, List<Class>> subclasses = <Class, List<Class>>{}; |
Set<Class> classesInFragment = new Set<Class>(); |
for (Library library in fragment.libraries) { |
@@ -840,12 +842,7 @@ class FragmentEmitter { |
emitInheritanceForClass(superclass); |
} |
- js.Expression superclassReference = (superclass == null) |
- ? new js.LiteralNull() |
- : classReference(superclass); |
- |
- inheritCalls.add( |
- js.js('inherit(#, #)', [classReference(cls), superclassReference])); |
+ subclasses.putIfAbsent(superclass, () => <Class>[]).add(cls); |
emittedClasses.add(cls); |
} |
@@ -856,18 +853,37 @@ class FragmentEmitter { |
if (cls.isMixinApplication) { |
MixinApplication mixin = cls; |
- mixinCalls.add(js.js('mixin(#, #)', |
+ mixinCalls.add(js.js.statement('mixin(#, #)', |
[classReference(cls), classReference(mixin.mixinClass)])); |
} |
} |
} |
+ js.Expression temp = null; |
+ for (Class superclass in subclasses.keys) { |
+ List<Class> list = subclasses[superclass]; |
+ js.Expression superclassReference = (superclass == null) |
+ ? new js.LiteralNull() |
+ : classReference(superclass); |
+ if (list.length == 1) { |
+ inheritCalls.add(js.js.statement('inherit(#, #)', |
+ [classReference(list.single), superclassReference])); |
+ } else { |
+ if (temp == null) { |
+ inheritCalls.add(js.js.statement('var _ = #', superclassReference)); |
+ temp = js.js('_'); |
+ } else { |
+ inheritCalls.add(js.js.statement('_ = #', superclassReference)); |
+ } |
+ for (Class cls in list) { |
+ inheritCalls |
+ .add(js.js.statement('inherit(#, _)', classReference(cls))); |
+ } |
+ } |
+ } |
+ |
return wrapPhase( |
- 'inheritance', |
- js.js.statement('{#; #;}', [ |
- inheritCalls.map((e) => new js.ExpressionStatement(e)), |
- mixinCalls.map((e) => new js.ExpressionStatement(e)) |
- ])); |
+ 'inheritance', js.js.statement('{#; #;}', [inheritCalls, mixinCalls])); |
} |
/// Emits the setup of method aliases. |