From f36a6987e489e62240ca571df55557b80ddfe594 Mon Sep 17 00:00:00 2001 From: Daniel Tschinder Date: Sun, 17 Mar 2019 21:41:35 -0700 Subject: [PATCH] Correctly preserve reference to array in for-of loop (#9697) * Correctly preserve reference to array in for-of loop * Add more tests --- .../misc/regression-1169/output.js | 5 +++-- .../src/index.js | 20 ++++++++----------- .../for-of-as-array/for-of-redeclare/input.js | 3 +++ .../for-of-redeclare/output.js | 4 ++++ .../test/fixtures/opt/array-binding/output.js | 10 ++++++---- .../regression/redeclare-array-8913/input.js | 5 +++++ .../regression/redeclare-array-8913/output.js | 8 ++++++++ .../fixtures/regression/scope-9696/exec.js | 9 +++++++++ .../fixtures/regression/scope-9696/input.js | 6 ++++++ .../fixtures/regression/scope-9696/output.js | 8 ++++++++ 10 files changed, 60 insertions(+), 18 deletions(-) create mode 100644 packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclare/input.js create mode 100644 packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclare/output.js create mode 100644 packages/babel-plugin-transform-for-of/test/fixtures/regression/redeclare-array-8913/input.js create mode 100644 packages/babel-plugin-transform-for-of/test/fixtures/regression/redeclare-array-8913/output.js create mode 100644 packages/babel-plugin-transform-for-of/test/fixtures/regression/scope-9696/exec.js create mode 100644 packages/babel-plugin-transform-for-of/test/fixtures/regression/scope-9696/input.js create mode 100644 packages/babel-plugin-transform-for-of/test/fixtures/regression/scope-9696/output.js diff --git a/packages/babel-core/test/fixtures/transformation/misc/regression-1169/output.js b/packages/babel-core/test/fixtures/transformation/misc/regression-1169/output.js index d2974e11c46d..b258a68cc05e 100644 --- a/packages/babel-core/test/fixtures/transformation/misc/regression-1169/output.js +++ b/packages/babel-core/test/fixtures/transformation/misc/regression-1169/output.js @@ -1,9 +1,10 @@ function foo() { var input = ['a', 'b', 'c']; var output = {}; + var _arr = input; - for (var _i = 0; _i < input.length; _i++) { - var c = input[_i]; + for (var _i = 0; _i < _arr.length; _i++) { + var c = _arr[_i]; var name = c; output[name] = name; } diff --git a/packages/babel-plugin-transform-for-of/src/index.js b/packages/babel-plugin-transform-for-of/src/index.js index 582e47bdb172..7e2954d1cd51 100644 --- a/packages/babel-plugin-transform-for-of/src/index.js +++ b/packages/babel-plugin-transform-for-of/src/index.js @@ -118,18 +118,14 @@ export default declare((api, options) => { function _ForOfStatementArray(path) { const { node, scope } = path; - const nodes = []; - let right = node.right; - - if (!t.isIdentifier(right) || !scope.hasBinding(right.name)) { - const uid = scope.generateUid("arr"); - nodes.push( - t.variableDeclaration("var", [ - t.variableDeclarator(t.identifier(uid), right), - ]), - ); - right = t.identifier(uid); - } + + const uid = scope.generateUid("arr"); + const nodes = [ + t.variableDeclaration("var", [ + t.variableDeclarator(t.identifier(uid), node.right), + ]), + ]; + const right = t.identifier(uid); const iterationKey = scope.generateUidIdentifier("i"); 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/input.js new file mode 100644 index 000000000000..3abfab88f65b --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclare/input.js @@ -0,0 +1,3 @@ +for (let o of arr) { + const arr = o; +} 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/output.js new file mode 100644 index 000000000000..81a8e0ef45fb --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/for-of-as-array/for-of-redeclare/output.js @@ -0,0 +1,4 @@ +for (let _i = 0, _arr = arr; _i < _arr.length; _i++) { + let o = _arr[_i]; + const arr = o; +} diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/opt/array-binding/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/opt/array-binding/output.js index ffdfc695cfb1..c5a09159312f 100644 --- a/packages/babel-plugin-transform-for-of/test/fixtures/opt/array-binding/output.js +++ b/packages/babel-plugin-transform-for-of/test/fixtures/opt/array-binding/output.js @@ -1,11 +1,13 @@ const x = []; +var _arr = x; -for (var _i = 0; _i < x.length; _i++) { - const y = x[_i]; +for (var _i = 0; _i < _arr.length; _i++) { + const y = _arr[_i]; } const arr = Object.entries(x); +var _arr2 = arr; -for (var _i2 = 0; _i2 < arr.length; _i2++) { - const y = arr[_i2]; +for (var _i2 = 0; _i2 < _arr2.length; _i2++) { + const y = _arr2[_i2]; } diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/regression/redeclare-array-8913/input.js b/packages/babel-plugin-transform-for-of/test/fixtures/regression/redeclare-array-8913/input.js new file mode 100644 index 000000000000..9b14e068e020 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/regression/redeclare-array-8913/input.js @@ -0,0 +1,5 @@ +function f(...t) { + for (let o of t) { + const t = o; + } +} diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/regression/redeclare-array-8913/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/regression/redeclare-array-8913/output.js new file mode 100644 index 000000000000..841eb701dd61 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/regression/redeclare-array-8913/output.js @@ -0,0 +1,8 @@ +function f(...t) { + var _arr = t; + + for (var _i = 0; _i < _arr.length; _i++) { + let o = _arr[_i]; + const t = o; + } +} diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/regression/scope-9696/exec.js b/packages/babel-plugin-transform-for-of/test/fixtures/regression/scope-9696/exec.js new file mode 100644 index 000000000000..05e8b874a7b2 --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/regression/scope-9696/exec.js @@ -0,0 +1,9 @@ +var arr = [1, 2, 3]; +var results = []; + +for (let v of arr) { + results.push(v); + arr = null; +} + +expect(results).toEqual([1, 2, 3]); diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/regression/scope-9696/input.js b/packages/babel-plugin-transform-for-of/test/fixtures/regression/scope-9696/input.js new file mode 100644 index 000000000000..a146399f4b6d --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/regression/scope-9696/input.js @@ -0,0 +1,6 @@ +var arr = [1,2,3] + +for (let v of arr) { + console.log(v) + arr = null +} diff --git a/packages/babel-plugin-transform-for-of/test/fixtures/regression/scope-9696/output.js b/packages/babel-plugin-transform-for-of/test/fixtures/regression/scope-9696/output.js new file mode 100644 index 000000000000..e98d98872e8e --- /dev/null +++ b/packages/babel-plugin-transform-for-of/test/fixtures/regression/scope-9696/output.js @@ -0,0 +1,8 @@ +var arr = [1, 2, 3]; +var _arr = arr; + +for (var _i = 0; _i < _arr.length; _i++) { + let v = _arr[_i]; + console.log(v); + arr = null; +}