Fix break/continue when switch is nested inside loop (#11802)
* Fix break/continue when switch is nested inside loop * merge retCheck
This commit is contained in:
parent
b1a8e72e16
commit
58cfaf20ee
@ -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;
|
||||
});
|
||||
@ -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;
|
||||
}
|
||||
})();
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user