diff --git a/packages/babel-plugin-transform-parameters/src/params.ts b/packages/babel-plugin-transform-parameters/src/params.ts index cb06d87bc934..f021da8e0531 100644 --- a/packages/babel-plugin-transform-parameters/src/params.ts +++ b/packages/babel-plugin-transform-parameters/src/params.ts @@ -154,7 +154,8 @@ export default function convertFunctionParams( // ensure it's a block, useful for arrow functions path.ensureBlock(); - if (state.needsOuterBinding || shadowedParams.size > 0 || node.generator) { + const { async, generator } = node; + if (generator || state.needsOuterBinding || shadowedParams.size > 0) { body.push(buildScopeIIFE(shadowedParams, path.node.body)); path.set("body", t.blockStatement(body as t.Statement[])); @@ -169,12 +170,21 @@ export default function convertFunctionParams( // This is an IIFE, so we don't need to worry about the noNewArrows assumption arrowPath.arrowFunctionToExpression(); - arrowPath.node.generator = path.node.generator; - arrowPath.node.async = path.node.async; - - // We don't reset "async" because if the default value of a parameter - // throws, it must reject asynchronously. - path.node.generator = false; + arrowPath.node.generator = generator; + arrowPath.node.async = async; + + node.generator = false; + node.async = false; + // If the default value of a parameter throws, it must reject asynchronously. + if (async) { + path.node.body = template.statement.ast`{ + try { + ${path.node.body.body} + } catch (e) { + return Promise.reject(e); + } + }` as t.BlockStatement; + } } else { path.get("body").unshiftContainer("body", body); } diff --git a/packages/babel-plugin-transform-parameters/test/fixtures/regression/15145/exec.js b/packages/babel-plugin-transform-parameters/test/fixtures/regression/15145/exec.js new file mode 100644 index 000000000000..8d618893f39f --- /dev/null +++ b/packages/babel-plugin-transform-parameters/test/fixtures/regression/15145/exec.js @@ -0,0 +1,10 @@ +async function * foo (p = 1) { + yield "hello"; + yield p; +} + +return (async () => { + const res = []; + for await (const x of foo()) res.push(x); + expect(res).toEqual(["hello", 1]); +})(); diff --git a/packages/babel-plugin-transform-parameters/test/fixtures/regression/15145/options.json b/packages/babel-plugin-transform-parameters/test/fixtures/regression/15145/options.json new file mode 100644 index 000000000000..3c3b32ce22b0 --- /dev/null +++ b/packages/babel-plugin-transform-parameters/test/fixtures/regression/15145/options.json @@ -0,0 +1,6 @@ +{ + "plugins": ["transform-parameters"], + "parserOpts": { + "allowReturnOutsideFunction": true + } +} diff --git a/packages/babel-plugin-transform-parameters/test/fixtures/regression/scope-gen-async/output.js b/packages/babel-plugin-transform-parameters/test/fixtures/regression/scope-gen-async/output.js index ef80025a587e..1f08dd53dd31 100644 --- a/packages/babel-plugin-transform-parameters/test/fixtures/regression/scope-gen-async/output.js +++ b/packages/babel-plugin-transform-parameters/test/fixtures/regression/scope-gen-async/output.js @@ -5,17 +5,25 @@ function f() { return a; }(a); } -async function g() { - let a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; - return async function (a) { - var a = await a; - return a; - }(a); +function g() { + try { + let a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; + return async function (a) { + var a = await a; + return a; + }(a); + } catch (e) { + return Promise.reject(e); + } } -async function h() { - let a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; - return async function* (a) { - var a = await (yield a); - return a; - }(a); +function h() { + try { + let a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; + return async function* (a) { + var a = await (yield a); + return a; + }(a); + } catch (e) { + return Promise.reject(e); + } }