Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - regenerator: allow nested finally block #601

Closed
wants to merge 14 commits into from
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: Bug report
about: Create a report to help us improve
about: Use this when swc breaks something
title: ''
labels: C-bug
assignees: ''
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: Crash report
about: Create a report to help us improve
about: Use this when swc panics
title: 'panic: '
labels: C-bug
assignees: ''
Expand Down
15 changes: 15 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
name: Feature request
about: Use this when you want a new feature
title: ''
labels: ''
assignees: ''

---

**Describe the feature**

**Babel plugin or link to the feature description**

**Additional context**
Add any other context about the problem here.
10 changes: 10 additions & 0 deletions .github/ISSUE_TEMPLATE/question.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
name: Question
about: Use this when you have a question
title: ''
labels: ''
assignees: ''

---

**Question**
26 changes: 18 additions & 8 deletions ecmascript/transforms/src/compat/es2015/regenerator/case.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ impl<'a> CaseHandler<'a> {
}

impl CaseHandler<'_> {
fn with_entry<F, Ret>(&mut self, entry: Entry, op: F) -> Ret
fn with_entry<F>(&mut self, entry: Entry, op: F)
where
F: FnOnce(&mut Self) -> Ret,
F: FnOnce(&mut Self),
{
self.leaps.push(entry);
let ret = op(self);
Expand All @@ -92,15 +92,20 @@ impl CaseHandler<'_> {
return None;
}

let mut last_loc_value = 0;
// let mut last_loc_value = 0;
Some(ArrayLit {
span: DUMMY_SP,
elems: replace(&mut self.try_entries, Default::default())
.into_iter()
.map(|entry: TryEntry| {
let this_loc_value = entry.first_loc;
assert!(this_loc_value.stmt_index >= last_loc_value);
last_loc_value = this_loc_value.stmt_index;
// let this_loc_value = entry.first_loc;
// assert!(
// this_loc_value.stmt_index >= last_loc_value,
// "this_loc_value = {:?}; last_loc_value = {};",
// this_loc_value,
// last_loc_value
// );
// last_loc_value = this_loc_value.stmt_index;

let ce = entry.catch_entry;
let fe = entry.finally_entry;
Expand Down Expand Up @@ -1091,7 +1096,7 @@ impl CaseHandler<'_> {
};

self.update_ctx_prev_loc(Some(&mut try_entry.first_loc));

// TODO: Track unmarked entries in a separate field,
self.with_entry(Entry::TryEntry(try_entry.clone()), |folder| {
//
folder.explode_stmts(block.stmts);
Expand Down Expand Up @@ -1343,7 +1348,12 @@ impl CaseHandler<'_> {
self.mark(after);
}

Stmt::Decl(_) | Stmt::ForOf(_) => self.emit(s),
Stmt::ForOf(s) => unreachable!(
"for-of statement should be removed by es2015::for_of pass\n{:?}",
s
),

Stmt::Decl(_) => self.emit(s),
}
}
}
Expand Down
4 changes: 1 addition & 3 deletions ecmascript/transforms/src/compat/es2015/regenerator/hoist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,9 @@ impl Fold<VarDecl> for Hoister {

impl Fold<VarDeclOrExpr> for Hoister {
fn fold(&mut self, var: VarDeclOrExpr) -> VarDeclOrExpr {
let var = var.fold_children(self);

match var {
VarDeclOrExpr::VarDecl(var) => VarDeclOrExpr::Expr(box self.var_decl_to_expr(var)),
_ => var,
_ => var.fold_children(self),
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions ecmascript/transforms/src/compat/es2015/regenerator/leap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ impl LeapManager {
pub fn push(&mut self, entry: Entry) {
self.stack.push(entry);
}
pub fn pop(&mut self) {
self.stack.pop();
pub fn pop(&mut self) -> Option<Entry> {
self.stack.pop()
}

pub fn find_leap_loc<F>(&self, mut pred: F, label: Option<&JsWord>) -> Option<Loc>
Expand Down
55 changes: 54 additions & 1 deletion ecmascript/transforms/tests/es2015_regenerator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
use swc_common::chain;
use swc_ecma_parser::Syntax;
use swc_ecma_transforms::{
compat::es2015::regenerator, modules::common_js::common_js, pass::Pass, resolver,
compat::{es2015, es2015::regenerator, es2016, es2017, es2017::async_to_generator},
modules::common_js::common_js,
pass::Pass,
resolver,
};

#[macro_use]
Expand Down Expand Up @@ -965,3 +968,53 @@ expect(v.next()).toEqual({ value: 4, done: false });
expect(v.next()).toEqual({ done: true });
"
);

test_exec!(
syntax(),
|_| chain!(es2017(), es2016(), es2015(Default::default()),),
issue_600_full,
"async function foo(b) {
for (let a of b) {
await a
}
}"
);

test_exec!(
syntax(),
|_| chain!(
async_to_generator(),
es2015::for_of(Default::default()),
es2015::regenerator(),
),
issue_600_exact_passes,
"async function foo(b) {
for (let a of b) {
await a
}
}"
);

test_exec!(
syntax(),
|_| es2015::regenerator(),
issue_600_min,
"function* foo() {
try {
yield 1;
throw new Error('1')
} finally{
try {
yield 2;
} finally{
throw new Error('2');
}
}
}

var v = foo();
expect(v.next()).toEqual({ value: 1, done: false });
expect(v.next()).toEqual({ value: 2, done: false });
expect(() => v.next()).toThrow('2')
"
);
23 changes: 23 additions & 0 deletions ecmascript/transforms/tests/es2017_async_to_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2105,3 +2105,26 @@ async function foo() {}

"#
);

// async_to_generator_parameters
test!(
syntax(),
|_| async_to_generator(),
issue_600,
r#"
async function foo() {
for (let a of b) {
}
}
"#,
"function _foo() {
_foo = _asyncToGenerator(function*() {
for (let a of b){
}
});
return _foo.apply(this, arguments);
}
function foo() {
return _foo.apply(this, arguments);
}"
);