Do not remove let bindings even they are wrapped in closure (#10343)
* fix: should not remove let binding even it is wrapped in closure Fixes #10339 * fix: remove bindings defined in blockScope when wrapped in closure * Move test assertions to the top level to ensure that they run
This commit is contained in:
parent
b0acfb24dd
commit
563874c06c
@ -441,22 +441,25 @@ class BlockScoping {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateScopeInfo(wrappedInClosure) {
|
updateScopeInfo(wrappedInClosure) {
|
||||||
const scope = this.scope;
|
const blockScope = this.blockPath.scope;
|
||||||
|
|
||||||
const parentScope = scope.getFunctionParent() || scope.getProgramParent();
|
const parentScope =
|
||||||
|
blockScope.getFunctionParent() || blockScope.getProgramParent();
|
||||||
const letRefs = this.letReferences;
|
const letRefs = this.letReferences;
|
||||||
|
|
||||||
for (const key of Object.keys(letRefs)) {
|
for (const key of Object.keys(letRefs)) {
|
||||||
const ref = letRefs[key];
|
const ref = letRefs[key];
|
||||||
const binding = scope.getBinding(ref.name);
|
const binding = blockScope.getBinding(ref.name);
|
||||||
if (!binding) continue;
|
if (!binding) continue;
|
||||||
if (binding.kind === "let" || binding.kind === "const") {
|
if (binding.kind === "let" || binding.kind === "const") {
|
||||||
binding.kind = "var";
|
binding.kind = "var";
|
||||||
|
|
||||||
if (wrappedInClosure) {
|
if (wrappedInClosure) {
|
||||||
scope.removeBinding(ref.name);
|
if (blockScope.hasOwnBinding(ref.name)) {
|
||||||
|
blockScope.removeBinding(ref.name);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
scope.moveBindingTo(ref.name, parentScope);
|
blockScope.moveBindingTo(ref.name, parentScope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
38
packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10339/exec.js
vendored
Normal file
38
packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10339/exec.js
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
const code = multiline([
|
||||||
|
"for (const {foo, ...bar} of { bar: [] }) {",
|
||||||
|
"() => foo;",
|
||||||
|
"const [qux] = bar;",
|
||||||
|
"try {} catch (e) {",
|
||||||
|
"let quux = qux;",
|
||||||
|
"}",
|
||||||
|
"}"
|
||||||
|
]);
|
||||||
|
|
||||||
|
let programPath;
|
||||||
|
let forOfPath;
|
||||||
|
let functionPath;
|
||||||
|
|
||||||
|
transform(code, {
|
||||||
|
configFile: false,
|
||||||
|
plugins: [
|
||||||
|
"../../../../lib",
|
||||||
|
{
|
||||||
|
post({ path }) {
|
||||||
|
programPath = path;
|
||||||
|
path.traverse({
|
||||||
|
ForOfStatement(path) { forOfPath = path },
|
||||||
|
FunctionExpression(path) { functionPath = path }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(Object.keys(programPath.scope.bindings)).toEqual(["foo", "bar"]);
|
||||||
|
|
||||||
|
// for declarations should be transformed to for bindings
|
||||||
|
expect(forOfPath.scope.bindings).toEqual({});
|
||||||
|
// The body should be wrapped into closure
|
||||||
|
expect(forOfPath.get("body").scope.bindings).toEqual({});
|
||||||
|
|
||||||
|
expect(Object.keys(functionPath.scope.bindings)).toEqual(["foo", "bar", "qux", "quux"]);
|
||||||
7
packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10339/input.js
vendored
Normal file
7
packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10339/input.js
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
for (const {foo, ...bar} of {}) {
|
||||||
|
() => foo;
|
||||||
|
const [qux] = bar;
|
||||||
|
try {} catch (e) {
|
||||||
|
const quux = qux;
|
||||||
|
}
|
||||||
|
}
|
||||||
3
packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10339/options.json
vendored
Normal file
3
packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10339/options.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"plugins": ["transform-block-scoping", ["proposal-object-rest-spread", { "loose": true }]]
|
||||||
|
}
|
||||||
20
packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10339/output.js
vendored
Normal file
20
packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10339/output.js
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
||||||
|
|
||||||
|
var _loop = function (foo, bar) {
|
||||||
|
() => foo;
|
||||||
|
|
||||||
|
var [qux] = bar;
|
||||||
|
|
||||||
|
try {} catch (e) {
|
||||||
|
var quux = qux;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var _ref of {}) {
|
||||||
|
var {
|
||||||
|
foo
|
||||||
|
} = _ref,
|
||||||
|
bar = _objectWithoutPropertiesLoose(_ref, ["foo"]);
|
||||||
|
|
||||||
|
_loop(foo, bar);
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user