Chromium Code Reviews| 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..32f338436eade618dcd2fdf93db934760c13fbc7 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 Set<ClassElement>(); |
|
vsm
2015/11/10 23:20:29
Not sure I need a Set here, but with the load-on-d
Jennifer Messerly
2015/11/10 23:32:09
yeah seems fine. small nit: you could use HashSet,
vsm
2015/11/10 23:41:50
Done.
|
| + |
| + 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)) { |
|
Jennifer Messerly
2015/11/10 23:32:09
parens not needed around ==
vsm
2015/11/10 23:41:50
Done.
|
| + 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] = () => #;', [ |