diff --git a/packages/babel-plugin-transform-block-scoping/src/index.js b/packages/babel-plugin-transform-block-scoping/src/index.js index 50c254c848a8..5391032751c4 100644 --- a/packages/babel-plugin-transform-block-scoping/src/index.js +++ b/packages/babel-plugin-transform-block-scoping/src/index.js @@ -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); } } } diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10339/exec.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10339/exec.js new file mode 100644 index 000000000000..9fea95129bb4 --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10339/exec.js @@ -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"]); diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10339/input.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10339/input.js new file mode 100644 index 000000000000..dcca3b6e2d97 --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10339/input.js @@ -0,0 +1,7 @@ +for (const {foo, ...bar} of {}) { + () => foo; + const [qux] = bar; + try {} catch (e) { + const quux = qux; + } +} diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10339/options.json b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10339/options.json new file mode 100644 index 000000000000..d829970edd1b --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10339/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["transform-block-scoping", ["proposal-object-rest-spread", { "loose": true }]] +} diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10339/output.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10339/output.js new file mode 100644 index 000000000000..b482807df22a --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10339/output.js @@ -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); +}