diff --git a/ecmascript/transforms/compat/Cargo.toml b/ecmascript/transforms/compat/Cargo.toml index e16c489fb6d..9301498b5f2 100644 --- a/ecmascript/transforms/compat/Cargo.toml +++ b/ecmascript/transforms/compat/Cargo.toml @@ -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] diff --git a/ecmascript/transforms/compat/src/es2015/regenerator/case.rs b/ecmascript/transforms/compat/src/es2015/regenerator/case.rs index aa23db45233..339cb069323 100644 --- a/ecmascript/transforms/compat/src/es2015/regenerator/case.rs +++ b/ecmascript/transforms/compat/src/es2015/regenerator/case.rs @@ -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); diff --git a/ecmascript/transforms/compat/src/es2015/regenerator/leap.rs b/ecmascript/transforms/compat/src/es2015/regenerator/leap.rs index 3fe3b1ad782..429f5be5330 100644 --- a/ecmascript/transforms/compat/src/es2015/regenerator/leap.rs +++ b/ecmascript/transforms/compat/src/es2015/regenerator/leap.rs @@ -64,6 +64,7 @@ impl LeapManager { pub fn find_continue_loc(&self, label: Option<&JsWord>) -> Option { self.find_leap_loc( |entry| match *entry { + Entry::Labeled { break_loc, .. } => Some(break_loc), Entry::Loop { continue_loc, .. } => Some(continue_loc), _ => None, }, diff --git a/ecmascript/transforms/compat/tests/es2015_regenerator.rs b/ecmascript/transforms/compat/tests/es2015_regenerator.rs index 3d0e6b6a7b7..18f5f125a3e 100644 --- a/ecmascript/transforms/compat/tests/es2015_regenerator.rs +++ b/ecmascript/transforms/compat/tests/es2015_regenerator.rs @@ -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 + }); +"# +);