Skip to content

Commit

Permalink
Fix break/continue when switch is nested inside loop (#11802)
Browse files Browse the repository at this point in the history
* Fix break/continue when switch is nested inside loop

* merge retCheck
  • Loading branch information
existentialism committed Jul 7, 2020
1 parent b1a8e72 commit 58cfaf2
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 60 deletions.
51 changes: 11 additions & 40 deletions packages/babel-plugin-transform-block-scoping/src/index.js
Expand Up @@ -844,55 +844,26 @@ class BlockScoping {

buildHas(ret: string) {
const body = this.body;

let retCheck;
const has = this.has;
const cases = [];

if (has.hasReturn) {
// typeof ret === "object"
retCheck = buildRetCheck({
RETURN: t.identifier(ret),
});
}

if (has.hasBreakContinue) {
for (const key of Object.keys(has.map)) {
cases.push(t.switchCase(t.stringLiteral(key), [has.map[key]]));
}

if (has.hasReturn) {
cases.push(t.switchCase(null, [retCheck]));
}

if (cases.length === 1) {
const single = cases[0];
body.push(
t.ifStatement(
t.binaryExpression("===", t.identifier(ret), single.test),
single.consequent[0],
t.binaryExpression("===", t.identifier(ret), t.stringLiteral(key)),
has.map[key],
),
);
} else {
if (this.loop) {
// https://github.com/babel/babel/issues/998
for (let i = 0; i < cases.length; i++) {
const caseConsequent = cases[i].consequent[0];
if (t.isBreakStatement(caseConsequent) && !caseConsequent.label) {
if (!this.loopLabel) {
this.loopLabel = this.scope.generateUidIdentifier("loop");
}
caseConsequent.label = t.cloneNode(this.loopLabel);
}
}
}

body.push(t.switchStatement(t.identifier(ret), cases));
}
} else {
if (has.hasReturn) {
body.push(retCheck);
}
}

// typeof ret === "object"
if (has.hasReturn) {
body.push(
buildRetCheck({
RETURN: t.identifier(ret),
}),
);
}
}
}
@@ -0,0 +1,15 @@
expect(() => {
for (const a of [1]) {
switch (true) {
case true: {
const b = 1;
() => b;
if (true) break;
continue;
}
case false: {
throw new Error("unreachable");
}
}
}
}).not.toThrow();
@@ -0,0 +1,13 @@
for (const a of [1]) {
switch (true) {
case true: {
const b = 1;
() => b;
if (true) break;
continue;
}
case false: {
throw new Error("unreachable");
}
}
}
@@ -0,0 +1,25 @@
for (var a of [1]) {
switch (true) {
case true:
{
var _ret = function () {
var b = 1;

(function () {
return b;
});

if (true) return "break";
return "continue";
}();

if (_ret === "break") break;
if (_ret === "continue") continue;
}

case false:
{
throw new Error("unreachable");
}
}
}
@@ -1,5 +1,5 @@
(function () {
var _loop2 = function (i) {
var _loop = function (i) {
fns.push(function () {
return i;
});
Expand All @@ -15,18 +15,11 @@
}
};

_loop: for (var i in nums) {
var _ret = _loop2(i);
for (var i in nums) {
var _ret = _loop(i);

switch (_ret) {
case "continue":
continue;

case "break":
break _loop;

default:
if (typeof _ret === "object") return _ret.v;
}
if (_ret === "continue") continue;
if (_ret === "break") break;
if (typeof _ret === "object") return _ret.v;
}
})();
Expand Up @@ -18,13 +18,8 @@ function foo() {
return "break";
}();

switch (_ret) {
case "break":
break;

default:
if (typeof _ret === "object") return _ret.v;
}
if (_ret === "break") break;
if (typeof _ret === "object") return _ret.v;
}
}
}
Expand Down

0 comments on commit 58cfaf2

Please sign in to comment.