diff --git a/packages/babel/src/transformation/transformers/es6/parameters/rest.js b/packages/babel/src/transformation/transformers/es6/parameters/rest.js index 97a2430588..963e070d17 100644 --- a/packages/babel/src/transformation/transformers/es6/parameters/rest.js +++ b/packages/babel/src/transformation/transformers/es6/parameters/rest.js @@ -223,7 +223,22 @@ export var visitor = { } else { // perform allocation at the lowest common denominator of all references loop._blockHoist = 1; - this.getEarliestCommonAncestorFrom(state.references).getStatementParent().insertBefore(loop); + + var target = this.getEarliestCommonAncestorFrom(state.references).getStatementParent(); + + // don't perform the allocation inside a loop + var highestLoop; + target.findParent(function (path) { + if (path.isLoop()) { + highestLoop = path; + } else if (path.isFunction()) { + // stop crawling up for functions + return true; + } + }); + if (highestLoop) target = highestLoop; + + target.insertBefore(loop); } } }; diff --git a/packages/babel/test/fixtures/transformation/es6.parameters/rest-deepest-common-ancestor-earliest-child/actual.js b/packages/babel/test/fixtures/transformation/es6.parameters/rest-deepest-common-ancestor-earliest-child/actual.js index 9b3b52c1f7..3f3606cb0a 100644 --- a/packages/babel/test/fixtures/transformation/es6.parameters/rest-deepest-common-ancestor-earliest-child/actual.js +++ b/packages/babel/test/fixtures/transformation/es6.parameters/rest-deepest-common-ancestor-earliest-child/actual.js @@ -50,3 +50,19 @@ function a(...args) { console.log("Shouldn't args be from a's scope?", args); }; } + +// loop +function runQueue(queue, ...args) { + for (let i = 0; i < queue.length; i++) { + queue[i](...args) + } +} + +// nested loop +function runQueue(queue, ...args) { + if (foo) { + for (let i = 0; i < queue.length; i++) { + queue[i](...args) + } + } +} diff --git a/packages/babel/test/fixtures/transformation/es6.parameters/rest-deepest-common-ancestor-earliest-child/expected.js b/packages/babel/test/fixtures/transformation/es6.parameters/rest-deepest-common-ancestor-earliest-child/expected.js index 0af3b93483..0e517c545b 100644 --- a/packages/babel/test/fixtures/transformation/es6.parameters/rest-deepest-common-ancestor-earliest-child/expected.js +++ b/packages/babel/test/fixtures/transformation/es6.parameters/rest-deepest-common-ancestor-earliest-child/expected.js @@ -77,3 +77,27 @@ function a() { console.log("Shouldn't args be from a's scope?", args); }; } + +// loop +function runQueue(queue) { + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + for (var i = 0; i < queue.length; i++) { + queue[i].apply(queue, args); + } +} + +// nested loop +function runQueue(queue) { + if (foo) { + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + for (var i = 0; i < queue.length; i++) { + queue[i].apply(queue, args); + } + } +}