diff --git a/packages/babel-plugin-transform-for-of/src/index.js b/packages/babel-plugin-transform-for-of/src/index.js index 85d6034f3ffd..4e203f8a7a83 100644 --- a/packages/babel-plugin-transform-for-of/src/index.js +++ b/packages/babel-plugin-transform-for-of/src/index.js @@ -19,7 +19,7 @@ export default declare((api, options) => { visitor: { ForOfStatement(path) { const { scope } = path; - const { left, right, body, await: isAwait } = path.node; + const { left, right, await: isAwait } = path.node; if (isAwait) { return; } @@ -48,8 +48,19 @@ export default declare((api, options) => { ); } - const block = t.toBlock(body); - block.body.unshift(assignment); + let blockBody; + const body = path.get("body"); + if ( + body.isBlockStatement() && + Object.keys(path.getBindingIdentifiers()).some(id => + body.scope.hasOwnBinding(id), + ) + ) { + blockBody = t.blockStatement([assignment, body.node]); + } else { + blockBody = t.toBlock(body.node); + blockBody.body.unshift(assignment); + } path.replaceWith( t.forStatement( @@ -60,7 +71,7 @@ export default declare((api, options) => { t.memberExpression(t.cloneNode(array), t.identifier("length")), ), t.updateExpression("++", t.cloneNode(i)), - block, + blockBody, ), ); }, diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-partial-redeclaration-in-body-array-pattern/input.js b/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-partial-redeclaration-in-body-array-pattern/input.js new file mode 100644 index 000000000000..9c42dd07cf92 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-partial-redeclaration-in-body-array-pattern/input.js @@ -0,0 +1,5 @@ +for (const [head, ...tail] of array) { + const head = 1; + console.log(tail); + console.log(head); +} diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-partial-redeclaration-in-body-array-pattern/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-partial-redeclaration-in-body-array-pattern/output.js new file mode 100644 index 000000000000..d10f3cea1988 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-partial-redeclaration-in-body-array-pattern/output.js @@ -0,0 +1,8 @@ +for (let _i = 0, _array = array; _i < _array.length; _i++) { + const [head, ...tail] = _array[_i]; + { + const head = 1; + console.log(tail); + console.log(head); + } +} diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-partial-redeclaration-in-body-object-pattern/input.js b/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-partial-redeclaration-in-body-object-pattern/input.js new file mode 100644 index 000000000000..5d9d07cdff54 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-partial-redeclaration-in-body-object-pattern/input.js @@ -0,0 +1,5 @@ +for (const [type, ...rest] of array) { + const type = 1; + console.log(rest); + console.log(type); +} diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-partial-redeclaration-in-body-object-pattern/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-partial-redeclaration-in-body-object-pattern/output.js new file mode 100644 index 000000000000..bca1a961708b --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-partial-redeclaration-in-body-object-pattern/output.js @@ -0,0 +1,8 @@ +for (let _i = 0, _array = array; _i < _array.length; _i++) { + const [type, ...rest] = _array[_i]; + { + const type = 1; + console.log(rest); + console.log(type); + } +} diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclaration-in-body-array-pattern/input.js b/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclaration-in-body-array-pattern/input.js new file mode 100644 index 000000000000..150e02bcd775 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclaration-in-body-array-pattern/input.js @@ -0,0 +1,6 @@ +for (const [head, ...tail] of array) { + const head = 1; + let tail; + console.log(tail); + console.log(head); +} diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclaration-in-body-array-pattern/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclaration-in-body-array-pattern/output.js new file mode 100644 index 000000000000..bb103233d714 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclaration-in-body-array-pattern/output.js @@ -0,0 +1,9 @@ +for (let _i = 0, _array = array; _i < _array.length; _i++) { + const [head, ...tail] = _array[_i]; + { + const head = 1; + let tail; + console.log(tail); + console.log(head); + } +} diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclaration-in-body-object-pattern/input.js b/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclaration-in-body-object-pattern/input.js new file mode 100644 index 000000000000..756ecda0da25 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclaration-in-body-object-pattern/input.js @@ -0,0 +1,6 @@ +for (const {type, ...rest} of array) { + const type = 1; + let rest; + console.log(rest); + console.log(type); +} diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclaration-in-body-object-pattern/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclaration-in-body-object-pattern/output.js new file mode 100644 index 000000000000..03a45647d69f --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclaration-in-body-object-pattern/output.js @@ -0,0 +1,12 @@ +for (let _i = 0, _array = array; _i < _array.length; _i++) { + const { + type, + ...rest + } = _array[_i]; + { + const type = 1; + let rest; + console.log(rest); + console.log(type); + } +} diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclaration-in-body/input.js b/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclaration-in-body/input.js new file mode 100644 index 000000000000..ded052290862 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclaration-in-body/input.js @@ -0,0 +1,3 @@ +for (const elm of array) { + const elm = 2; +} diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclaration-in-body/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclaration-in-body/output.js new file mode 100644 index 000000000000..f05d069d547d --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclaration-in-body/output.js @@ -0,0 +1,6 @@ +for (let _i = 0, _array = array; _i < _array.length; _i++) { + const elm = _array[_i]; + { + const elm = 2; + } +} diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclare/input.js b/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclare-iterable/input.js similarity index 100% rename from packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclare/input.js rename to packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclare-iterable/input.js diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclare/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclare-iterable/output.js similarity index 100% rename from packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclare/output.js rename to packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclare-iterable/output.js