From 5ecd0f75d2d2db813ebf9683031e0532eb112768 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Thu, 8 Apr 2021 10:04:20 -0400 Subject: [PATCH] fix: hoist variable declaration within do block --- .../variable-declaration-start.js | 11 +++-- .../variable-declaration-within-function.js | 8 ++++ packages/babel-traverse/package.json | 1 + .../babel-traverse/src/path/replacement.ts | 41 +++++-------------- yarn.lock | 1 + 5 files changed, 28 insertions(+), 34 deletions(-) create mode 100644 packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/variable-declaration-within-function.js diff --git a/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/variable-declaration-start.js b/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/variable-declaration-start.js index 5e5027c56c21..6f5c411593db 100644 --- a/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/variable-declaration-start.js +++ b/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/variable-declaration-start.js @@ -1,4 +1,7 @@ -expect(do { - var bar = "foo"; - bar; -}).toBe("foo"); +expect( + do { + var bar = "foo"; + bar; + } +).toBe("foo"); +expect(bar).toBe("foo"); diff --git a/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/variable-declaration-within-function.js b/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/variable-declaration-within-function.js new file mode 100644 index 000000000000..a58b208ec7c6 --- /dev/null +++ b/packages/babel-plugin-proposal-do-expressions/test/fixtures/do-expressions/variable-declaration-within-function.js @@ -0,0 +1,8 @@ +expect( + () => do { + () => { + var bar = "foo"; + }; + bar; + } +).toThrow(ReferenceError); diff --git a/packages/babel-traverse/package.json b/packages/babel-traverse/package.json index 1ce31ae23f74..3d28d4f61704 100644 --- a/packages/babel-traverse/package.json +++ b/packages/babel-traverse/package.json @@ -19,6 +19,7 @@ "@babel/code-frame": "workspace:^7.12.13", "@babel/generator": "workspace:^7.13.9", "@babel/helper-function-name": "workspace:^7.12.13", + "@babel/helper-hoist-variables": "workspace:^7.13.0", "@babel/helper-split-export-declaration": "workspace:^7.12.13", "@babel/parser": "workspace:^7.13.13", "@babel/types": "workspace:^7.13.13", diff --git a/packages/babel-traverse/src/path/replacement.ts b/packages/babel-traverse/src/path/replacement.ts index abb5d0551481..3ff5de7f3ecb 100644 --- a/packages/babel-traverse/src/path/replacement.ts +++ b/packages/babel-traverse/src/path/replacement.ts @@ -6,35 +6,7 @@ import NodePath from "./index"; import { path as pathCache } from "../cache"; import { parse } from "@babel/parser"; import * as t from "@babel/types"; - -const hoistVariablesVisitor = { - Function(path) { - path.skip(); - }, - - VariableDeclaration(path) { - if (path.node.kind !== "var") return; - - const bindings = path.getBindingIdentifiers(); - for (const key of Object.keys(bindings)) { - path.scope.push({ id: bindings[key] }); - } - - const exprs = []; - - for (const declar of path.node.declarations as Array) { - if (declar.init) { - exprs.push( - t.expressionStatement( - t.assignmentExpression("=", declar.id, declar.init), - ), - ); - } - } - - path.replaceWithMultiple(exprs); - }, -}; +import hoistVariables from "@babel/helper-hoist-variables"; /** * Replace a node with an array of multiple. This method performs the following steps: @@ -238,7 +210,16 @@ export function replaceExpressionWithStatements( t.CallExpression & { callee: t.ArrowFunctionExpression } >; - this.traverse(hoistVariablesVisitor); + // hoist variable declaration in do block + // `(do { var x = 1; x;})` -> `var x; (() => { x = 1; return x; })()` + const callee = (this as ThisType).get("callee"); + hoistVariables( + callee.get("body"), + id => { + this.scope.push({ id }); + }, + "var", + ); // add implicit returns to all ending expression statements const completionRecords: Array = (this as ThisType) diff --git a/yarn.lock b/yarn.lock index 605fda1024e0..2fdd7d652a53 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3492,6 +3492,7 @@ __metadata: "@babel/code-frame": "workspace:^7.12.13" "@babel/generator": "workspace:^7.13.9" "@babel/helper-function-name": "workspace:^7.12.13" + "@babel/helper-hoist-variables": "workspace:^7.13.0" "@babel/helper-plugin-test-runner": "workspace:*" "@babel/helper-split-export-declaration": "workspace:^7.12.13" "@babel/parser": "workspace:^7.13.13"