diff --git a/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/await-yield/exec.js b/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/await-yield/exec.js new file mode 100644 index 000000000000..fce8d59e2eaa --- /dev/null +++ b/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/await-yield/exec.js @@ -0,0 +1,15 @@ +async function* asyncGenerator(x) { + const y = do { + let z; + yield 3; + yield await x; + }; + + return y; +} + +const promise = Promise.resolve(5); +const gen = asyncGenerator(promise); +expect(gen.next()).resolves.toMatchObject({ value: 3, done: false }); +expect(gen.next()).resolves.toMatchObject({ value: 5, done: false }); +expect(gen.next(10)).resolves.toMatchObject({ value: 10, done: true }); diff --git a/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/await-yield/input.js b/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/await-yield/input.js new file mode 100644 index 000000000000..6e7fa1ff88ef --- /dev/null +++ b/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/await-yield/input.js @@ -0,0 +1,8 @@ +async function* asyncGenerator(x) { + const y = do { + let z; + yield await x; + }; + + return y; +} \ No newline at end of file diff --git a/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/await-yield/options.json b/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/await-yield/options.json new file mode 100644 index 000000000000..ae1d62e8aaa7 --- /dev/null +++ b/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/await-yield/options.json @@ -0,0 +1,3 @@ +{ + "minNodeVersion": "10.0.0" +} \ No newline at end of file diff --git a/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/await-yield/output.js b/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/await-yield/output.js new file mode 100644 index 000000000000..27f4e684b44a --- /dev/null +++ b/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/await-yield/output.js @@ -0,0 +1,7 @@ +async function* asyncGenerator(x) { + const y = yield* async function* () { + let z; + return yield await x; + }(); + return y; +} diff --git a/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/yield/exec.js b/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/yield/exec.js new file mode 100644 index 000000000000..90e7c35ed31b --- /dev/null +++ b/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/yield/exec.js @@ -0,0 +1,14 @@ +function * generator() { + yield 1; + const y = do { + let z; + yield 2; + }; + + return y; +} + +const gen = generator(); +expect(gen.next().value).toBe(1); +expect(gen.next().value).toBe(2); +expect(gen.next(3).value).toBe(3); \ No newline at end of file diff --git a/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/yield/input.js b/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/yield/input.js new file mode 100644 index 000000000000..a8fa76c8100e --- /dev/null +++ b/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/yield/input.js @@ -0,0 +1,8 @@ +function * g() { + const y = do { + let z; + yield 1; + }; + + return y; +} \ No newline at end of file diff --git a/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/yield/options.json b/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/yield/options.json new file mode 100644 index 000000000000..7edb6d2fc815 --- /dev/null +++ b/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/yield/options.json @@ -0,0 +1,3 @@ +{ + "minNodeVersion": "8.0.0" +} \ No newline at end of file diff --git a/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/yield/output.js b/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/yield/output.js new file mode 100644 index 000000000000..12f1022282a3 --- /dev/null +++ b/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/yield/output.js @@ -0,0 +1,7 @@ +function* g() { + const y = yield* function* () { + let z; + return yield 1; + }(); + return y; +} diff --git a/packages/babel-traverse/src/path/replacement.ts b/packages/babel-traverse/src/path/replacement.ts index e114740501e8..abb5d0551481 100644 --- a/packages/babel-traverse/src/path/replacement.ts +++ b/packages/babel-traverse/src/path/replacement.ts @@ -228,6 +228,7 @@ export function replaceExpressionWithStatements( const functionParent = this.getFunctionParent(); const isParentAsync = functionParent?.is("async"); + const isParentGenerator = functionParent?.is("generator"); const container = t.arrowFunctionExpression([], t.blockStatement(nodes)); @@ -277,16 +278,30 @@ export function replaceExpressionWithStatements( callee.arrowFunctionToExpression(); // (() => await xxx)() -> await (async () => await xxx)(); - if ( + const needToAwaitFunction = isParentAsync && traverse.hasType( (this.get("callee.body") as NodePath).node, "AwaitExpression", t.FUNCTION_TYPES, - ) - ) { + ); + const needToYieldFunction = + isParentGenerator && + traverse.hasType( + (this.get("callee.body") as NodePath).node, + "YieldExpression", + t.FUNCTION_TYPES, + ); + if (needToAwaitFunction) { callee.set("async", true); - this.replaceWith(t.awaitExpression((this as ThisType).node)); + // yield* will await the generator return result + if (!needToYieldFunction) { + this.replaceWith(t.awaitExpression((this as ThisType).node)); + } + } + if (needToYieldFunction) { + callee.set("generator", true); + this.replaceWith(t.yieldExpression((this as ThisType).node, true)); } return callee.get("body.body");