| Index: pkg/dev_compiler/lib/src/compiler/code_generator.dart
|
| diff --git a/pkg/dev_compiler/lib/src/compiler/code_generator.dart b/pkg/dev_compiler/lib/src/compiler/code_generator.dart
|
| index 231fcb9ca5ea894f036f6734af498bf974578885..b7f3d5a048c61f3eb83779eb8979cf64a025c04e 100644
|
| --- a/pkg/dev_compiler/lib/src/compiler/code_generator.dart
|
| +++ b/pkg/dev_compiler/lib/src/compiler/code_generator.dart
|
| @@ -767,7 +767,8 @@ class CodeGenerator extends GeneralizingAstVisitor
|
|
|
| // Emit things that come after the ES6 `class ... { ... }`.
|
| var jsPeerNames = _getJSPeerNames(classElem);
|
| - _setBaseClass(classElem, className, jsPeerNames, body);
|
| + JS.Statement deferredBaseClass =
|
| + _setBaseClass(classElem, className, jsPeerNames, body);
|
|
|
| _emitClassTypeTests(classElem, className, body);
|
|
|
| @@ -779,9 +780,11 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| _emitClassMetadata(node.metadata, className, body);
|
|
|
| JS.Statement classDef = _statement(body);
|
| +
|
| var typeFormals = classElem.typeParameters;
|
| if (typeFormals.isNotEmpty) {
|
| - classDef = _defineClassTypeArguments(classElem, typeFormals, classDef);
|
| + classDef = _defineClassTypeArguments(
|
| + classElem, typeFormals, classDef, className, deferredBaseClass);
|
| }
|
|
|
| body = <JS.Statement>[classDef];
|
| @@ -1126,14 +1129,23 @@ class CodeGenerator extends GeneralizingAstVisitor
|
|
|
| /// Wraps a possibly generic class in its type arguments.
|
| JS.Statement _defineClassTypeArguments(TypeDefiningElement element,
|
| - List<TypeParameterElement> formals, JS.Statement body) {
|
| + List<TypeParameterElement> formals, JS.Statement body,
|
| + [JS.Expression className, JS.Statement deferredBaseClass]) {
|
| assert(formals.isNotEmpty);
|
| - var genericCall = _callHelper('generic((#) => { #; #; return #; })', [
|
| + var typeConstructor = js.call('(#) => { #; #; return #; }', [
|
| _emitTypeFormals(formals),
|
| _typeTable.discharge(formals),
|
| body,
|
| element.name
|
| ]);
|
| +
|
| + var genericArgs = [typeConstructor];
|
| + if (deferredBaseClass != null) {
|
| + genericArgs.add(js.call('(#) => { #; }', [className, deferredBaseClass]));
|
| + }
|
| +
|
| + var genericCall = _callHelper('generic(#)', [genericArgs]);
|
| +
|
| if (element.library.isDartAsync &&
|
| (element.name == "Future" || element.name == "_Future")) {
|
| genericCall = _callHelper('flattenFutures(#)', [genericCall]);
|
| @@ -1601,9 +1613,10 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| }
|
| }
|
|
|
| - void _setBaseClass(ClassElement classElem, JS.Expression className,
|
| + JS.Statement _setBaseClass(ClassElement classElem, JS.Expression className,
|
| List<String> jsPeerNames, List<JS.Statement> body) {
|
| - if (jsPeerNames.isNotEmpty && classElem.typeParameters.isNotEmpty) {
|
| + var typeFormals = classElem.typeParameters;
|
| + if (jsPeerNames.isNotEmpty && typeFormals.isNotEmpty) {
|
| for (var peer in jsPeerNames) {
|
| // TODO(jmesserly): we should just extend Array in the first place
|
| var newBaseClass = _callHelper('global.#', [peer]);
|
| @@ -1613,9 +1626,12 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| } else if (_hasDeferredSupertype.contains(classElem)) {
|
| var newBaseClass = _emitType(classElem.type.superclass,
|
| nameType: false, subClass: classElem, className: className);
|
| - body.add(_callHelperStatement(
|
| - 'setBaseClass(#, #);', [className, newBaseClass]));
|
| + var deferredBaseClass = _callHelperStatement(
|
| + 'setBaseClass(#, #);', [className, newBaseClass]);
|
| + if (typeFormals.isNotEmpty) return deferredBaseClass;
|
| + body.add(deferredBaseClass);
|
| }
|
| + return null;
|
| }
|
|
|
| void _defineNamedConstructors(List<ConstructorDeclaration> ctors,
|
| @@ -2954,7 +2970,7 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| hoistType: hoistType,
|
| subClass: subClass,
|
| className: className));
|
| - } else if (lowerGeneric) {
|
| + } else if (lowerGeneric || element == subClass) {
|
| jsArgs = [];
|
| }
|
| if (jsArgs != null) {
|
|
|