Skip to content

Commit

Permalink
fix: hoist variable declaration within do block
Browse files Browse the repository at this point in the history
  • Loading branch information
JLHwung committed Apr 8, 2021
1 parent be1003b commit 5ecd0f7
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 34 deletions.
@@ -1,4 +1,7 @@
expect(do {
var bar = "foo";
bar;
}).toBe("foo");
expect(
do {
var bar = "foo";
bar;
}
).toBe("foo");
expect(bar).toBe("foo");
@@ -0,0 +1,8 @@
expect(
() => do {
() => {
var bar = "foo";
};
bar;
}
).toThrow(ReferenceError);
1 change: 1 addition & 0 deletions packages/babel-traverse/package.json
Expand Up @@ -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",
Expand Down
41 changes: 11 additions & 30 deletions packages/babel-traverse/src/path/replacement.ts
Expand Up @@ -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<any>) {
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:
Expand Down Expand Up @@ -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<NodePath> = (this as ThisType)
Expand Down
1 change: 1 addition & 0 deletions yarn.lock
Expand Up @@ -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"
Expand Down

0 comments on commit 5ecd0f7

Please sign in to comment.