From 2220167903aa1ba8726ae2e459184191e7981f0a Mon Sep 17 00:00:00 2001 From: Amjad Masad Date: Tue, 3 Nov 2015 17:05:41 -0800 Subject: [PATCH] Fix recursion in async-to-generator transforms We're naming the inner generator function in the name of the original async function. This means when people have recursive await calls it refers to the generator version. Which is fine if we had a `yield *` (delegate). However, if not it leads to returning an unresolved generator object. We can either capture all recursive calls and add a delegate, which becomes really hard with expressions. I choose to have the name reserved to the exposed function `retFunction`. Fixes #2782 --- .../named-expression/expected.js | 4 +-- .../async-to-generator/parameters/expected.js | 2 +- .../async-to-generator/statement/expected.js | 2 +- .../named-expression/expected.js | 4 +-- .../bluebird-coroutines/statement/expected.js | 2 +- .../src/index.js | 26 ++++++++++--------- 6 files changed, 21 insertions(+), 19 deletions(-) diff --git a/packages/babel-core/test/fixtures/transformation/async-to-generator/named-expression/expected.js b/packages/babel-core/test/fixtures/transformation/async-to-generator/named-expression/expected.js index e727401db9..d1ce465a7a 100644 --- a/packages/babel-core/test/fixtures/transformation/async-to-generator/named-expression/expected.js +++ b/packages/babel-core/test/fixtures/transformation/async-to-generator/named-expression/expected.js @@ -1,8 +1,8 @@ var foo = (function () { - var ref = babelHelpers.asyncToGenerator(function* bar() { + var ref = babelHelpers.asyncToGenerator(function* () { console.log(bar); }); - return function foo() { + return function bar() { return ref.apply(this, arguments); }; })(); diff --git a/packages/babel-core/test/fixtures/transformation/async-to-generator/parameters/expected.js b/packages/babel-core/test/fixtures/transformation/async-to-generator/parameters/expected.js index a8012824ed..22fc56a52c 100644 --- a/packages/babel-core/test/fixtures/transformation/async-to-generator/parameters/expected.js +++ b/packages/babel-core/test/fixtures/transformation/async-to-generator/parameters/expected.js @@ -1,5 +1,5 @@ let foo = (function () { - var ref = babelHelpers.asyncToGenerator(function* foo(bar) {}); + var ref = babelHelpers.asyncToGenerator(function* (bar) {}); return function foo(_x) { return ref.apply(this, arguments); }; diff --git a/packages/babel-core/test/fixtures/transformation/async-to-generator/statement/expected.js b/packages/babel-core/test/fixtures/transformation/async-to-generator/statement/expected.js index 063c0f4e12..e6ced836b5 100644 --- a/packages/babel-core/test/fixtures/transformation/async-to-generator/statement/expected.js +++ b/packages/babel-core/test/fixtures/transformation/async-to-generator/statement/expected.js @@ -1,5 +1,5 @@ let foo = (function () { - var ref = babelHelpers.asyncToGenerator(function* foo() { + var ref = babelHelpers.asyncToGenerator(function* () { var wat = yield bar(); }); return function foo() { diff --git a/packages/babel-core/test/fixtures/transformation/bluebird-coroutines/named-expression/expected.js b/packages/babel-core/test/fixtures/transformation/bluebird-coroutines/named-expression/expected.js index 5dfc5e1f0d..32b58b8fd7 100644 --- a/packages/babel-core/test/fixtures/transformation/bluebird-coroutines/named-expression/expected.js +++ b/packages/babel-core/test/fixtures/transformation/bluebird-coroutines/named-expression/expected.js @@ -1,10 +1,10 @@ import { coroutine as _coroutine } from "bluebird"; var foo = (function () { - var ref = _coroutine(function* bar() { + var ref = _coroutine(function* () { console.log(bar); }); - return function foo() { + return function bar() { return ref.apply(this, arguments); }; })(); diff --git a/packages/babel-core/test/fixtures/transformation/bluebird-coroutines/statement/expected.js b/packages/babel-core/test/fixtures/transformation/bluebird-coroutines/statement/expected.js index a2688cb525..3433c86c89 100644 --- a/packages/babel-core/test/fixtures/transformation/bluebird-coroutines/statement/expected.js +++ b/packages/babel-core/test/fixtures/transformation/bluebird-coroutines/statement/expected.js @@ -1,7 +1,7 @@ import { coroutine as _coroutine } from "bluebird"; let foo = (function () { - var ref = _coroutine(function* foo() { + var ref = _coroutine(function* () { var wat = yield bar(); }); diff --git a/packages/babel-helper-remap-async-to-generator/src/index.js b/packages/babel-helper-remap-async-to-generator/src/index.js index 1e84a4fec7..c7d089083c 100644 --- a/packages/babel-helper-remap-async-to-generator/src/index.js +++ b/packages/babel-helper-remap-async-to-generator/src/index.js @@ -46,6 +46,9 @@ function plainFunction(path: NodePath, callId: Object) { node.async = false; node.generator = true; + let asyncFnId = node.id; + node.id = null; + let built = t.callExpression(callId, [node]); let container = buildWrapper({ FUNCTION: built, @@ -57,25 +60,24 @@ function plainFunction(path: NodePath, callId: Object) { if (path.isFunctionDeclaration()) { let declar = t.variableDeclaration("let", [ t.variableDeclarator( - t.identifier(node.id.name), + t.identifier(asyncFnId.name), t.callExpression(container, []) ) ]); declar._blockHoist = true; - nameFunction({ - node: retFunction, - parent: declar.declarations[0], - scope: path.scope - }); - + retFunction.id = asyncFnId; path.replaceWith(declar); } else { - nameFunction({ - node: retFunction, - parent: path.parent, - scope: path.scope - }); + if (asyncFnId && asyncFnId.name) { + retFunction.id = asyncFnId; + } else { + nameFunction({ + node: retFunction, + parent: path.parent, + scope: path.scope + }); + } if (retFunction.id || node.params.length) { // we have an inferred function id or params so we need this wrapper