From 6347eaf2cd357d50a993c3925c8eb80b94f712dc Mon Sep 17 00:00:00 2001 From: Yokubjon-J Date: Mon, 27 Jun 2022 13:10:42 +0500 Subject: [PATCH] Transform `await` in computed class keys (#14391) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * test added * import correct tests * config file simplified Co-authored-by: Nicolò Ribaudo * environmentVisitor merged but issue still persists * <> is run * Rename test file * peerDependencies added, path.skip() removed and ArrowFunctionExpression skip added * Update packages/babel-plugin-proposal-async-generator-functions/src/index.ts Co-authored-by: Nicolò Ribaudo * modified yarn.lock Co-authored-by: Nicolò Ribaudo --- .../package.json | 4 + .../src/index.ts | 35 ++++---- .../package.json | 1 + .../src/index.ts | 90 ++++++++++--------- .../transform-class-keys/input.js | 9 ++ .../transform-class-keys/options.json | 3 + .../transform-class-keys/output.js | 18 ++++ yarn.lock | 4 + 8 files changed, 107 insertions(+), 57 deletions(-) create mode 100644 packages/babel-plugin-proposal-async-generator-functions/test/fixtures/async-generators/transform-class-keys/input.js create mode 100644 packages/babel-plugin-proposal-async-generator-functions/test/fixtures/async-generators/transform-class-keys/options.json create mode 100644 packages/babel-plugin-proposal-async-generator-functions/test/fixtures/async-generators/transform-class-keys/output.js diff --git a/packages/babel-helper-remap-async-to-generator/package.json b/packages/babel-helper-remap-async-to-generator/package.json index e0946d241a4d..6afec5e141b8 100644 --- a/packages/babel-helper-remap-async-to-generator/package.json +++ b/packages/babel-helper-remap-async-to-generator/package.json @@ -15,12 +15,16 @@ "main": "./lib/index.js", "dependencies": { "@babel/helper-annotate-as-pure": "workspace:^", + "@babel/helper-environment-visitor": "workspace:^", "@babel/helper-wrap-function": "workspace:^", "@babel/types": "workspace:^" }, "devDependencies": { "@babel/traverse": "workspace:^" }, + "peerDependencies": { + "@babel/core": "workspace:^" + }, "engines": { "node": ">=6.9.0" }, diff --git a/packages/babel-helper-remap-async-to-generator/src/index.ts b/packages/babel-helper-remap-async-to-generator/src/index.ts index d15b95842791..876372f6110c 100644 --- a/packages/babel-helper-remap-async-to-generator/src/index.ts +++ b/packages/babel-helper-remap-async-to-generator/src/index.ts @@ -1,8 +1,10 @@ /* @noflow */ -import type { NodePath, Visitor } from "@babel/traverse"; +import type { NodePath } from "@babel/traverse"; import wrapFunction from "@babel/helper-wrap-function"; import annotateAsPure from "@babel/helper-annotate-as-pure"; +import environmentVisitor from "@babel/helper-environment-visitor"; +import { traverse } from "@babel/core"; import { callExpression, cloneNode, @@ -12,23 +14,26 @@ import { } from "@babel/types"; import type * as t from "@babel/types"; -const awaitVisitor: Visitor<{ wrapAwait: t.Expression }> = { - Function(path) { - path.skip(); - }, +const awaitVisitor = traverse.visitors.merge<{ wrapAwait: t.Expression }>([ + { + ArrowFunctionExpression(path) { + path.skip(); + }, - AwaitExpression(path, { wrapAwait }) { - const argument = path.get("argument"); + AwaitExpression(path, { wrapAwait }) { + const argument = path.get("argument"); - path.replaceWith( - yieldExpression( - wrapAwait - ? callExpression(cloneNode(wrapAwait), [argument.node]) - : argument.node, - ), - ); + path.replaceWith( + yieldExpression( + wrapAwait + ? callExpression(cloneNode(wrapAwait), [argument.node]) + : argument.node, + ), + ); + }, }, -}; + environmentVisitor, +]); export default function ( path: NodePath, diff --git a/packages/babel-plugin-proposal-async-generator-functions/package.json b/packages/babel-plugin-proposal-async-generator-functions/package.json index cb0df7bbe0cc..0b665ee4c529 100644 --- a/packages/babel-plugin-proposal-async-generator-functions/package.json +++ b/packages/babel-plugin-proposal-async-generator-functions/package.json @@ -17,6 +17,7 @@ "babel-plugin" ], "dependencies": { + "@babel/helper-environment-visitor": "workspace:^", "@babel/helper-plugin-utils": "workspace:^", "@babel/helper-remap-async-to-generator": "workspace:^", "@babel/plugin-syntax-async-generators": "^7.8.4" diff --git a/packages/babel-plugin-proposal-async-generator-functions/src/index.ts b/packages/babel-plugin-proposal-async-generator-functions/src/index.ts index b9cc7734baf2..c732072554de 100644 --- a/packages/babel-plugin-proposal-async-generator-functions/src/index.ts +++ b/packages/babel-plugin-proposal-async-generator-functions/src/index.ts @@ -1,66 +1,72 @@ import { declare } from "@babel/helper-plugin-utils"; import remapAsyncToGenerator from "@babel/helper-remap-async-to-generator"; import syntaxAsyncGenerators from "@babel/plugin-syntax-async-generators"; -import { types as t } from "@babel/core"; -import type { PluginPass } from "@babel/core"; import type { NodePath, Visitor } from "@babel/traverse"; +import { traverse, types as t, type PluginPass } from "@babel/core"; import rewriteForAwait from "./for-await"; +import environmentVisitor from "@babel/helper-environment-visitor"; export default declare(api => { api.assertVersion(7); - const yieldStarVisitor: Visitor = { - Function(path) { - path.skip(); - }, + const yieldStarVisitor = traverse.visitors.merge([ + { + ArrowFunctionExpression(path) { + path.skip(); + }, - YieldExpression({ node }, state) { - if (!node.delegate) return; - const callee = state.addHelper("asyncGeneratorDelegate"); - node.argument = t.callExpression(callee, [ - t.callExpression(state.addHelper("asyncIterator"), [node.argument]), - state.addHelper("awaitAsyncGenerator"), - ]); + YieldExpression({ node }, state) { + if (!node.delegate) return; + const callee = state.addHelper("asyncGeneratorDelegate"); + node.argument = t.callExpression(callee, [ + t.callExpression(state.addHelper("asyncIterator"), [node.argument]), + state.addHelper("awaitAsyncGenerator"), + ]); + }, }, - }; + environmentVisitor, + ]); - const forAwaitVisitor: Visitor = { - Function(path) { - path.skip(); - }, + const forAwaitVisitor = traverse.visitors.merge([ + { + ArrowFunctionExpression(path) { + path.skip(); + }, - ForOfStatement(path: NodePath, { file }) { - const { node } = path; - if (!node.await) return; + ForOfStatement(path: NodePath, { file }) { + const { node } = path; + if (!node.await) return; - const build = rewriteForAwait(path, { - getAsyncIterator: file.addHelper("asyncIterator"), - }); + const build = rewriteForAwait(path, { + getAsyncIterator: file.addHelper("asyncIterator"), + }); - const { declar, loop } = build; - const block = loop.body as t.BlockStatement; + const { declar, loop } = build; + const block = loop.body as t.BlockStatement; - // ensure that it's a block so we can take all its statements - path.ensureBlock(); + // ensure that it's a block so we can take all its statements + path.ensureBlock(); - // add the value declaration to the new loop body - if (declar) { - block.body.push(declar); - } + // add the value declaration to the new loop body + if (declar) { + block.body.push(declar); + } - // push the rest of the original loop body onto our new body - block.body.push(...path.node.body.body); + // push the rest of the original loop body onto our new body + block.body.push(...path.node.body.body); - t.inherits(loop, node); - t.inherits(loop.body, node.body); + t.inherits(loop, node); + t.inherits(loop.body, node.body); - if (build.replaceParent) { - path.parentPath.replaceWithMultiple(build.node); - } else { - path.replaceWithMultiple(build.node); - } + if (build.replaceParent) { + path.parentPath.replaceWithMultiple(build.node); + } else { + path.replaceWithMultiple(build.node); + } + }, }, - }; + environmentVisitor, + ]); const visitor: Visitor = { Function(path, state) { diff --git a/packages/babel-plugin-proposal-async-generator-functions/test/fixtures/async-generators/transform-class-keys/input.js b/packages/babel-plugin-proposal-async-generator-functions/test/fixtures/async-generators/transform-class-keys/input.js new file mode 100644 index 000000000000..e60f3a0bd9fe --- /dev/null +++ b/packages/babel-plugin-proposal-async-generator-functions/test/fixtures/async-generators/transform-class-keys/input.js @@ -0,0 +1,9 @@ +async function* fn() { + class A { + [yield 1]() {} + } + + class B extends A { + [await 1]() {} + } +} \ No newline at end of file diff --git a/packages/babel-plugin-proposal-async-generator-functions/test/fixtures/async-generators/transform-class-keys/options.json b/packages/babel-plugin-proposal-async-generator-functions/test/fixtures/async-generators/transform-class-keys/options.json new file mode 100644 index 000000000000..90a4a0981b00 --- /dev/null +++ b/packages/babel-plugin-proposal-async-generator-functions/test/fixtures/async-generators/transform-class-keys/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["proposal-async-generator-functions"] +} \ No newline at end of file diff --git a/packages/babel-plugin-proposal-async-generator-functions/test/fixtures/async-generators/transform-class-keys/output.js b/packages/babel-plugin-proposal-async-generator-functions/test/fixtures/async-generators/transform-class-keys/output.js new file mode 100644 index 000000000000..037bd06072ef --- /dev/null +++ b/packages/babel-plugin-proposal-async-generator-functions/test/fixtures/async-generators/transform-class-keys/output.js @@ -0,0 +1,18 @@ +function fn() { + return _fn.apply(this, arguments); +} + +function _fn() { + _fn = babelHelpers.wrapAsyncGenerator(function* () { + class A { + [yield 1]() {} + + } + + class B extends A { + [yield babelHelpers.awaitAsyncGenerator(1)]() {} + + } + }); + return _fn.apply(this, arguments); +} diff --git a/yarn.lock b/yarn.lock index a5a03efd93b4..4ea79dbd6171 100644 --- a/yarn.lock +++ b/yarn.lock @@ -845,9 +845,12 @@ __metadata: resolution: "@babel/helper-remap-async-to-generator@workspace:packages/babel-helper-remap-async-to-generator" dependencies: "@babel/helper-annotate-as-pure": "workspace:^" + "@babel/helper-environment-visitor": "workspace:^" "@babel/helper-wrap-function": "workspace:^" "@babel/traverse": "workspace:^" "@babel/types": "workspace:^" + peerDependencies: + "@babel/core": "workspace:^" languageName: unknown linkType: soft @@ -1197,6 +1200,7 @@ __metadata: resolution: "@babel/plugin-proposal-async-generator-functions@workspace:packages/babel-plugin-proposal-async-generator-functions" dependencies: "@babel/core": "workspace:^" + "@babel/helper-environment-visitor": "workspace:^" "@babel/helper-plugin-test-runner": "workspace:^" "@babel/helper-plugin-utils": "workspace:^" "@babel/helper-remap-async-to-generator": "workspace:^"