Index: lib/src/codegen/js_codegen.dart |
diff --git a/lib/src/codegen/js_codegen.dart b/lib/src/codegen/js_codegen.dart |
index b41607f168acc516553c6ebae38e6797394e9a16..663786a19e0ae958168aef9fda664f2a612da0fa 100644 |
--- a/lib/src/codegen/js_codegen.dart |
+++ b/lib/src/codegen/js_codegen.dart |
@@ -1329,7 +1329,8 @@ class JSCodegenVisitor extends GeneralizingAstVisitor |
} |
JS.Fun _emitNativeFunctionBody( |
- List<JS.Parameter> params, MethodDeclaration node) { |
+ List<JS.Parameter> params, List<JS.Expression> paramRefs, |
+ MethodDeclaration node) { |
if (node.isStatic) { |
// TODO(vsm): Do we need to handle this case? |
return null; |
@@ -1345,10 +1346,10 @@ class JSCodegenVisitor extends GeneralizingAstVisitor |
return new JS.Fun(params, js.statement('{ return this.#; }', [name])); |
} else if (node.isSetter) { |
return new JS.Fun( |
- params, js.statement('{ this.# = #; }', [name, params.last])); |
+ params, js.statement('{ this.# = #; }', [name, paramRefs.last])); |
} else { |
return new JS.Fun( |
- params, js.statement('{ return this.#(#); }', [name, params])); |
+ params, js.statement('{ return this.#(#); }', [name, paramRefs])); |
} |
} |
@@ -1359,16 +1360,18 @@ class JSCodegenVisitor extends GeneralizingAstVisitor |
var params = _visit(node.parameters) as List<JS.Parameter>; |
if (params == null) params = <JS.Parameter>[]; |
+ var paramRefs = _emitParameterReferences(node.parameters); |
JS.Fun fn; |
if (_externalOrNative(node)) { |
- fn = _emitNativeFunctionBody(params, node); |
+ fn = _emitNativeFunctionBody(params, paramRefs, node); |
// TODO(vsm): Remove if / when we handle the static case above. |
if (fn == null) return null; |
} else { |
var typeParams = _emitTypeParams(node.element).toList(); |
var returnType = emitTypeRef(node.element.returnType); |
- fn = _emitFunctionBody(params, node.body, typeParams, returnType); |
+ fn = _emitFunctionBody( |
+ params, paramRefs, node.body, typeParams, returnType); |
} |
if (node.operatorKeyword != null && |
@@ -1547,7 +1550,9 @@ class JSCodegenVisitor extends GeneralizingAstVisitor |
var typeParams = _emitTypeParams(node.element).toList(); |
var returnType = emitTypeRef(node.element.returnType); |
if (parent is FunctionDeclaration) { |
- return _emitFunctionBody(params, node.body, typeParams, returnType); |
+ var paramRefs = _emitParameterReferences(node.parameters); |
+ return _emitFunctionBody( |
+ params, paramRefs, node.body, typeParams, returnType); |
} else { |
// Chrome Canary does not accept default values with destructuring in |
// arrow functions yet (e.g. `({a} = {}) => 1`) but happily accepts them |
@@ -1559,7 +1564,9 @@ class JSCodegenVisitor extends GeneralizingAstVisitor |
JS.Node jsBody; |
var body = node.body; |
if (body.isGenerator || body.isAsynchronous) { |
- jsBody = _emitGeneratorFunctionBody(params, body, returnType); |
+ var paramRefs = _emitParameterReferences(node.parameters); |
+ jsBody = _emitGeneratorFunctionBody( |
+ params, paramRefs, body, returnType); |
} else if (body is ExpressionFunctionBody) { |
jsBody = _visit(body.expression); |
} else { |
@@ -1582,14 +1589,19 @@ class JSCodegenVisitor extends GeneralizingAstVisitor |
} |
} |
- JS.Fun _emitFunctionBody(List<JS.Parameter> params, FunctionBody body, |
+ JS.Fun _emitFunctionBody(List<JS.Parameter> params, |
+ List<JS.Expression> paramRefs, FunctionBody body, |
List<JS.Identifier> typeParams, JS.TypeRef returnType) { |
// sync*, async, async* |
if (body.isAsynchronous || body.isGenerator) { |
+ // TODO(ochafik): Refine params: we don't need default values in the |
+ // nested function, so we'd need to generate a custom, simpler params |
+ // list here. |
return new JS.Fun( |
params, |
- js.statement('{ return #; }', |
- [_emitGeneratorFunctionBody(params, body, returnType)]), |
+ js.statement('{ return #; }', [ |
+ _emitGeneratorFunctionBody(params, paramRefs, body, returnType) |
+ ]), |
returnType: returnType); |
} |
// normal function (sync) |
@@ -1598,7 +1610,8 @@ class JSCodegenVisitor extends GeneralizingAstVisitor |
} |
JS.Expression _emitGeneratorFunctionBody( |
- List<JS.Parameter> params, FunctionBody body, JS.TypeRef returnType) { |
+ List<JS.Parameter> params, List<JS.Expression> paramRefs, |
+ FunctionBody body, JS.TypeRef returnType) { |
var kind = body.isSynchronous ? 'sync' : 'async'; |
if (body.isGenerator) kind += 'Star'; |
@@ -1652,7 +1665,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor |
var T = _emitTypeName(_getExpectedReturnType(body)); |
return js.call('dart.#(#)', [ |
kind, |
- [gen, T]..addAll(params) |
+ [gen, T]..addAll(paramRefs) |
]); |
} |
@@ -2164,6 +2177,17 @@ class JSCodegenVisitor extends GeneralizingAstVisitor |
List<JS.Parameter> visitFormalParameterList(FormalParameterList node) => |
_emitFormalParameterList(node); |
+ // TODO(ochafik): Decouple Parameter from Identifier. |
+ List<JS.Expression> _emitParameterReferences(FormalParameterList node) => |
+ node == null |
+ ? <JS.Expression>[] |
+ : _emitFormalParameterList(node, allowDestructuring: false) |
+ .map((JS.Parameter p) { |
+ if (p is JS.RestParameter) return new JS.Spread(p.parameter); |
+ return p as JS.Identifier; |
+ }) |
+ .toList(); |
+ |
List<JS.Parameter> _emitFormalParameterList(FormalParameterList node, |
{bool allowDestructuring: true}) { |
var result = <JS.Parameter>[]; |
@@ -2198,7 +2222,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor |
} else { |
var jsParam = _visit(param); |
result.add( |
- param is DefaultFormalParameter && options.destructureNamedParams |
+ param is DefaultFormalParameter && destructure |
? new JS.DestructuredVariable( |
name: jsParam, defaultValue: _defaultParamValue(param)) |
: jsParam); |