fix(es/transforms/compat): Fix regenerator (#1906)

swc_ecma_transforms_compat:
 - `regenerator`: Handle labeled continue jumps. (#1892)
This commit is contained in:
OJ Kwon 2021-07-08 22:13:16 -07:00 committed by GitHub
parent 03be315921
commit 480287aec4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 179 additions and 3 deletions

View File

@ -6,7 +6,7 @@ edition = "2018"
license = "Apache-2.0/MIT"
name = "swc_ecma_transforms_compat"
repository = "https://github.com/swc-project/swc.git"
version = "0.24.2"
version = "0.24.3"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

View File

@ -880,7 +880,11 @@ impl CaseHandler<'_> {
.as_arg();
if ty == "break" || ty == "continue" {
vec![ty_arg, target.unwrap().expr().as_arg()]
if let Some(arg) = target {
vec![ty_arg, arg.expr().as_arg()]
} else {
vec![ty_arg]
}
} else {
if let Some(arg) = arg {
vec![ty_arg, arg]
@ -1047,7 +1051,7 @@ impl CaseHandler<'_> {
label: s.label.sym.clone(),
break_loc: after,
},
|h| h.explode_stmt(*s.body, None),
|h| h.explode_stmt(*s.body, Some(s.label.sym)),
);
self.mark(after);

View File

@ -64,6 +64,7 @@ impl LeapManager {
pub fn find_continue_loc(&self, label: Option<&JsWord>) -> Option<Loc> {
self.find_leap_loc(
|entry| match *entry {
Entry::Labeled { break_loc, .. } => Some(break_loc),
Entry::Loop { continue_loc, .. } => Some(continue_loc),
_ => None,
},

View File

@ -1445,3 +1445,174 @@ test!(
}
"
);
test!(
syntax(),
|_| tr(Default::default()),
issue_1892,
r#"
function *gen() {
var firstTime = true;
outer:
while (true) {
yield 0;
try {
while (true) {
yield 1;
if (firstTime) {
firstTime = false;
yield 2;
continue outer;
} else {
yield 3;
break;
}
}
yield 4;
break;
} finally {
yield 5;
}
yield 6;
}
yield 7;
}
const iter = gen();
expect(iter.next()).toEqual({value: 0, done: false});
expect(iter.next()).toEqual({value: 1, done: false});
expect(iter.next()).toEqual({value: 2, done: false});
expect(iter.next()).toEqual({value: 5, done: false});
expect(iter.next()).toEqual({value: 0, done: false});
expect(iter.next()).toEqual({value: 1, done: false});
expect(iter.next()).toEqual({value: 3, done: false});
expect(iter.next()).toEqual({value: 4, done: false});
expect(iter.next()).toEqual({value: 5, done: false});
expect(iter.next()).toEqual({value: 7, done: false});
expect(iter.next()).toEqual({value: undefined, done: true});
"#,
r#"
var regeneratorRuntime = require("regenerator-runtime");
var _marked = regeneratorRuntime.mark(gen);
function gen() {
var firstTime;
return regeneratorRuntime.wrap(function gen$(_ctx) {
while(1)switch(_ctx.prev = _ctx.next){
case 0:
firstTime = true;
case 1:
if (!true) {
_ctx.next = 31;
break;
}
_ctx.next = 4;
return 0;
case 4:
_ctx.prev = 4;
case 5:
if (!true) {
_ctx.next = 20;
break;
}
_ctx.next = 8;
return 1;
case 8:
if (!firstTime) {
_ctx.next = 15;
break;
}
firstTime = false;
_ctx.next = 12;
return 2;
case 12:
return _ctx.abrupt("continue", 1);
case 15:
_ctx.next = 17;
return 3;
case 17:
return _ctx.abrupt("break", 20);
case 18:
_ctx.next = 5;
break;
case 20:
_ctx.next = 22;
return 4;
case 22:
return _ctx.abrupt("break", 31);
case 23:
_ctx.prev = 23;
_ctx.next = 26;
return 5;
case 26:
return _ctx.finish(23);
case 27:
_ctx.next = 29;
return 6;
case 29:
_ctx.next = 1;
break;
case 31:
_ctx.next = 33;
return 7;
case 33:
case "end":
return _ctx.stop();
}
}, _marked, null, [
[
4,
,
23,
27
]
]);
}
const iter = gen();
expect(iter.next()).toEqual({
value: 0,
done: false
});
expect(iter.next()).toEqual({
value: 1,
done: false
});
expect(iter.next()).toEqual({
value: 2,
done: false
});
expect(iter.next()).toEqual({
value: 5,
done: false
});
expect(iter.next()).toEqual({
value: 0,
done: false
});
expect(iter.next()).toEqual({
value: 1,
done: false
});
expect(iter.next()).toEqual({
value: 3,
done: false
});
expect(iter.next()).toEqual({
value: 4,
done: false
});
expect(iter.next()).toEqual({
value: 5,
done: false
});
expect(iter.next()).toEqual({
value: 7,
done: false
});
expect(iter.next()).toEqual({
value: undefined,
done: true
});
"#
);