Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not remove let bindings even they are wrapped in closure #10343

Merged
merged 3 commits into from Oct 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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);
}