From 056a995dd88c752c8d77813d8beab68e79c91b1d Mon Sep 17 00:00:00 2001 From: Artem Yavorsky Date: Tue, 14 Nov 2017 01:06:32 +0200 Subject: [PATCH] Fix shadow variables reassignment for block scoping in loops. (#6814) --- .../src/index.js | 9 +++++++++ .../exec/for-continuation-outer-reference.js | 13 +++++++++++++ .../actual.js | 7 +++++++ .../expected.js | 19 +++++++++++++++++++ 4 files changed, 48 insertions(+) create mode 100644 packages/babel-plugin-transform-block-scoping/test/fixtures/exec/for-continuation-outer-reference.js create mode 100644 packages/babel-plugin-transform-block-scoping/test/fixtures/general/wrap-closure-shadow-variables-reassignment/actual.js create mode 100644 packages/babel-plugin-transform-block-scoping/test/fixtures/general/wrap-closure-shadow-variables-reassignment/expected.js diff --git a/packages/babel-plugin-transform-block-scoping/src/index.js b/packages/babel-plugin-transform-block-scoping/src/index.js index c8519b2b89..3b14632af8 100644 --- a/packages/babel-plugin-transform-block-scoping/src/index.js +++ b/packages/babel-plugin-transform-block-scoping/src/index.js @@ -247,6 +247,8 @@ const continuationVisitor = { } state.reassignments[name] = true; } + } else if (path.isReturnStatement()) { + state.returnStatements.push(path); } }, }; @@ -585,6 +587,7 @@ class BlockScoping { addContinuations(fn) { const state = { reassignments: {}, + returnStatements: [], outsideReferences: this.outsideLetReferences, }; @@ -599,6 +602,12 @@ class BlockScoping { this.scope.rename(param.name, newParam.name, fn); + state.returnStatements.forEach(returnStatement => { + returnStatement.insertBefore( + t.expressionStatement(t.assignmentExpression("=", param, newParam)), + ); + }); + // assign outer reference as it's been modified internally and needs to be retained fn.body.body.push( t.expressionStatement(t.assignmentExpression("=", param, newParam)), diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/exec/for-continuation-outer-reference.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/exec/for-continuation-outer-reference.js new file mode 100644 index 0000000000..16a171d571 --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/exec/for-continuation-outer-reference.js @@ -0,0 +1,13 @@ +let data = [true, false, false, true, false]; + +for (let index = 0; index < data.length; index++) { + let item = data[index]; + if (!item) { + data.splice(index, 1); + index--; + continue; + } + let fn = function () {item;}; +} + +assert(data.every(item => item)); diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/wrap-closure-shadow-variables-reassignment/actual.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/wrap-closure-shadow-variables-reassignment/actual.js new file mode 100644 index 0000000000..617344c318 --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/wrap-closure-shadow-variables-reassignment/actual.js @@ -0,0 +1,7 @@ +for (let index = 0; index < 10; index++) { + if (index % 2) { + index+=3; + continue; + } + let fn = function () {index;}; +} diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/wrap-closure-shadow-variables-reassignment/expected.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/wrap-closure-shadow-variables-reassignment/expected.js new file mode 100644 index 0000000000..9259417146 --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/wrap-closure-shadow-variables-reassignment/expected.js @@ -0,0 +1,19 @@ +var _loop = function (_index) { + if (_index % 2) { + _index += 3; + index = _index; + return "continue"; + } + + var fn = function () { + _index; + }; + + index = _index; +}; + +for (var index = 0; index < 10; index++) { + var _ret = _loop(index); + + if (_ret === "continue") continue; +}