From c0299320f0169d0e5937fef244e4bacf9c3f0374 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sat, 31 Jan 2015 21:27:20 +1100 Subject: [PATCH] avoid transforming of inner labels and propagation of maps in block scoping transformer - #644 --- .../transformers/es6/block-scoping.js | 21 +++++++++++++++++-- .../es6-block-scoping-exec/nested-labels-4.js | 14 +++++++++++++ .../es6-let-scoping/.switch-break/exec.js | 11 ---------- 3 files changed, 33 insertions(+), 13 deletions(-) create mode 100644 test/fixtures/transformation/es6-block-scoping-exec/nested-labels-4.js delete mode 100644 test/fixtures/transformation/es6-let-scoping/.switch-break/exec.js diff --git a/lib/6to5/transformation/transformers/es6/block-scoping.js b/lib/6to5/transformation/transformers/es6/block-scoping.js index 2fb6c02cad..6ccc69ddc3 100644 --- a/lib/6to5/transformation/transformers/es6/block-scoping.js +++ b/lib/6to5/transformation/transformers/es6/block-scoping.js @@ -311,9 +311,9 @@ var loopVisitor = { var replace; if (t.isLoop(node)) { - state = clone(state); state.ignoreLabeless = true; traverse(node, loopVisitor, scope, state); + state.ignoreLabeless = false; } if (t.isFunction(node) || t.isLoop(node)) { @@ -324,9 +324,15 @@ var loopVisitor = { if (loopText) { if (node.label) { + // we shouldn't be transforming this because it exists somewhere inside + if (state.innerLabels.indexOf(node.label.name) >= 0) { + return; + } + loopText = loopText + "|" + node.label.name; } else { - // we shouldn't be dealing with this + // we shouldn't be transforming these statements because + // they don't refer to the actual loop we're scopifying if (state.ignoreLabeless) return; // break statements mean something different in this context @@ -352,6 +358,14 @@ var loopVisitor = { } }; +var loopLabelVisitor = { + enter: function (node, parent, scope, context, state) { + if (t.isLabeledStatement(node)) { + state.innerLabels.push(node.label.name); + } + } +}; + /** * If we're inside of a loop then traverse it and check if it has one of * the following node types `ReturnStatement`, `BreakStatement`, @@ -365,12 +379,15 @@ LetScoping.prototype.checkLoop = function () { var state = { hasBreakContinue: false, ignoreLabeless: false, + innerLabels: [], hasReturn: false, isLoop: !!this.loopParent, map: {} }; + traverse(this.block, loopLabelVisitor, this.scope, state); traverse(this.block, loopVisitor, this.scope, state); + return state; }; diff --git a/test/fixtures/transformation/es6-block-scoping-exec/nested-labels-4.js b/test/fixtures/transformation/es6-block-scoping-exec/nested-labels-4.js new file mode 100644 index 0000000000..f6a7fa54f1 --- /dev/null +++ b/test/fixtures/transformation/es6-block-scoping-exec/nested-labels-4.js @@ -0,0 +1,14 @@ +(function () { + var stack = []; + + loop1: + for (let j = 0; j < 10; j++) { + for (let i = 0; i < 10; i++) { + stack.push(() => [i, j]); + break loop1; + } + } + + assert.deepEqual(stack.length, 1); + assert.deepEqual(stack[0](), [0, 0]); +})(); diff --git a/test/fixtures/transformation/es6-let-scoping/.switch-break/exec.js b/test/fixtures/transformation/es6-let-scoping/.switch-break/exec.js deleted file mode 100644 index 0e7eb1fb2f..0000000000 --- a/test/fixtures/transformation/es6-let-scoping/.switch-break/exec.js +++ /dev/null @@ -1,11 +0,0 @@ -if (true) { - const x = 1; - switch (x) { - case 1: { - function y() { - assert(x, 1); - }; - break; - } - } -}