Skip to content

Commit

Permalink
Do not remove let bindings even they are wrapped in closure (#10343)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
JLHwung authored and nicolo-ribaudo committed Oct 8, 2019
1 parent b0acfb2 commit 563874c
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 5 deletions.
13 changes: 8 additions & 5 deletions packages/babel-plugin-transform-block-scoping/src/index.js
Expand Up @@ -441,22 +441,25 @@ class BlockScoping {
}

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;

for (const key of Object.keys(letRefs)) {
const ref = letRefs[key];
const binding = scope.getBinding(ref.name);
const binding = blockScope.getBinding(ref.name);
if (!binding) continue;
if (binding.kind === "let" || binding.kind === "const") {
binding.kind = "var";

if (wrappedInClosure) {
scope.removeBinding(ref.name);
if (blockScope.hasOwnBinding(ref.name)) {
blockScope.removeBinding(ref.name);
}
} else {
scope.moveBindingTo(ref.name, parentScope);
blockScope.moveBindingTo(ref.name, parentScope);
}
}
}
Expand Down
@@ -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"]);
@@ -0,0 +1,7 @@
for (const {foo, ...bar} of {}) {
() => foo;
const [qux] = bar;
try {} catch (e) {
const quux = qux;
}
}
@@ -0,0 +1,3 @@
{
"plugins": ["transform-block-scoping", ["proposal-object-rest-spread", { "loose": true }]]
}
@@ -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);
}

0 comments on commit 563874c

Please sign in to comment.