| Index: lib/src/codegen/js_codegen.dart
|
| diff --git a/lib/src/codegen/js_codegen.dart b/lib/src/codegen/js_codegen.dart
|
| index 0c46fb0ebb133d8fc1ed9b8310de3a491afc56e6..4e376ded4c78af616ad6223560a2f8ee6b609a5e 100644
|
| --- a/lib/src/codegen/js_codegen.dart
|
| +++ b/lib/src/codegen/js_codegen.dart
|
| @@ -566,6 +566,22 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
|
| [genericName, typeParams, body, name]);
|
| }
|
|
|
| + final _hasDeferredSupertype = new HashSet<ClassElement>();
|
| +
|
| + bool _deferIfNeeded(DartType type, ClassElement current) {
|
| + if (type is ParameterizedType) {
|
| + var typeArguments = type.typeArguments;
|
| + for (var typeArg in typeArguments) {
|
| + var typeElement = typeArg.element;
|
| + // FIXME(vsm): This does not track mutual recursive dependences.
|
| + if (current == typeElement || _deferIfNeeded(typeArg, current)) {
|
| + return true;
|
| + }
|
| + }
|
| + }
|
| + return false;
|
| + }
|
| +
|
| JS.Expression _classHeritage(ClassElement element) {
|
| var type = element.type;
|
| if (type.isObject) return null;
|
| @@ -573,7 +589,16 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
|
| // Assume we can load eagerly, until proven otherwise.
|
| _loader.startTopLevel(element);
|
|
|
| - JS.Expression heritage = _emitTypeName(type.superclass);
|
| + // Find the super type
|
| + JS.Expression heritage;
|
| + var supertype = type.superclass;
|
| + if (_deferIfNeeded(supertype, element)) {
|
| + // Fall back to raw type.
|
| + supertype = fillDynamicTypeArgs(supertype.element.type, rules.provider);
|
| + _hasDeferredSupertype.add(element);
|
| + }
|
| + heritage = _emitTypeName(supertype);
|
| +
|
| if (type.mixins.isNotEmpty) {
|
| var mixins = type.mixins.map(_emitTypeName).toList();
|
| mixins.insert(0, heritage);
|
| @@ -701,6 +726,12 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
|
| [classElem.name, _propertyName(jsPeerName)]));
|
| }
|
|
|
| + // Deferred Superclass
|
| + if (_hasDeferredSupertype.contains(classElem)) {
|
| + body.add(js.statement('#.prototype.__proto__ = #.prototype;',
|
| + [name, _emitTypeName(classElem.type.superclass)]));
|
| + }
|
| +
|
| // Interfaces
|
| if (classElem.interfaces.isNotEmpty) {
|
| body.add(js.statement('#[dart.implements] = () => #;', [
|
|
|