diff --git a/packages/babel-plugin-transform-block-scoping/src/index.js b/packages/babel-plugin-transform-block-scoping/src/index.js index 560368cf0fbf..6eb209a0d058 100644 --- a/packages/babel-plugin-transform-block-scoping/src/index.js +++ b/packages/babel-plugin-transform-block-scoping/src/index.js @@ -289,7 +289,7 @@ const loopVisitor = { }, "BreakStatement|ContinueStatement|ReturnStatement"(path, state) { - const { node, parent, scope } = path; + const { node, scope } = path; if (node[this.LOOP_IGNORE]) return; let replace; @@ -309,7 +309,7 @@ const loopVisitor = { if (state.ignoreLabeless) return; // break statements mean something different in this context - if (t.isBreakStatement(node) && t.isSwitchCase(parent)) return; + if (t.isBreakStatement(node) && state.inSwitchCase) return; } state.hasBreakContinue = true; diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/exec/switch-labeled-break.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/exec/switch-labeled-break.js new file mode 100644 index 000000000000..a81996184293 --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/exec/switch-labeled-break.js @@ -0,0 +1,14 @@ +// it shouldn't break on a case-break statement +var i; +the_loop: for (i = 0; i < 10; i++) { + switch (i) { + case 3: { + break the_loop; + } + } + + const z = 3; // to force the plugin to convert to loop function call + () => z; +} + +expect(i).toBe(3); diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/block-inside-switch-inside-loop/exec.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/block-inside-switch-inside-loop/exec.js new file mode 100644 index 000000000000..6ab05df0697c --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/block-inside-switch-inside-loop/exec.js @@ -0,0 +1,51 @@ +// it shouldn't break on a case-break statement +var i; +for (i = 0; i < 10; i++) { + switch (i) { + case 1: { + break; + } + } + + const z = 3; // to force the plugin to convert to loop function call + () => z; +} + +expect(i).toBe(10); + +// it should continue on continue statements within switch +var j = 0; +for (i = 0; i < 10; i++) { + switch (i) { + case 0: { + continue; + } + } + j++; + + const z = 3; + () => z; +} + +expect(j).toBe(9); + +// it should work with loops nested within switch +j = 0; +for (i = 0; i < 10; i++) { + switch (i) { + case 0: { + for (var k = 0; k < 10; k++) { + const z = 3; + () => z; + j++; + break; + } + break; + } + } + + const z = 3; + () => z; +} + +expect(j).toBe(1); diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/block-inside-switch-inside-loop/input.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/block-inside-switch-inside-loop/input.js new file mode 100644 index 000000000000..39e162890d03 --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/block-inside-switch-inside-loop/input.js @@ -0,0 +1,48 @@ +// it shouldn't break on a case-break statement +var i; +for (i = 0; i < 10; i++) { + switch (i) { + case 1: + break; + } + + const z = 3; // to force the plugin to convert to loop function call + () => z; +} + +expect(i).toBe(10); + +// it should continue on continue statements within switch +var j = 0; +for (i = 0; i < 10; i++) { + switch (i) { + case 0: + continue; + } + j++; + + const z = 3; + () => z; +} + +expect(j).toBe(9); + +// it should work with loops nested within switch +j = 0; +for (i = 0; i < 10; i++) { + switch (i) { + case 0: + for (var k = 0; k < 10; k++) { + const z = 3; + () => z; + j++; + break; + } + break; + } + + const z = 3; + () => z; +} + +expect(j).toBe(1); diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/block-inside-switch-inside-loop/output.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/block-inside-switch-inside-loop/output.js new file mode 100644 index 000000000000..2e502dabfae3 --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/block-inside-switch-inside-loop/output.js @@ -0,0 +1,85 @@ +// it shouldn't break on a case-break statement +var i; + +var _loop = function () { + switch (i) { + case 1: + break; + } + + var z = 3; // to force the plugin to convert to loop function call + + (function () { + return z; + }); +}; + +for (i = 0; i < 10; i++) { + _loop(); +} + +expect(i).toBe(10); // it should continue on continue statements within switch + +var j = 0; + +var _loop2 = function () { + switch (i) { + case 0: + return "continue"; + } + + j++; + var z = 3; + + (function () { + return z; + }); +}; + +for (i = 0; i < 10; i++) { + var _ret = _loop2(); + + if (_ret === "continue") continue; +} + +expect(j).toBe(9); // it should work with loops nested within switch + +j = 0; + +var _loop3 = function () { + switch (i) { + case 0: + var _loop4 = function () { + var z = 3; + + (function () { + return z; + }); + + j++; + return "break"; + }; + + for (k = 0; k < 10; k++) { + var _ret2 = _loop4(); + + if (_ret2 === "break") break; + } + + break; + } + + var z = 3; + + (function () { + return z; + }); +}; + +for (i = 0; i < 10; i++) { + var k; + + _loop3(); +} + +expect(j).toBe(1);