mirror of
https://github.com/swc-project/swc.git
synced 2024-12-23 13:51:19 +03:00
regenerator: allow nested finally block (#601)
Previously, ```js function *foo() { try { } finally { try { } finally { throw new Error('foo'); } } } ``` make swc panic Closes #600.
This commit is contained in:
parent
ec98516b0e
commit
20e37eae5d
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -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: ''
|
||||
|
@ -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: ''
|
15
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
15
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@ -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
.github/ISSUE_TEMPLATE/question.md
vendored
Normal file
10
.github/ISSUE_TEMPLATE/question.md
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
name: Question
|
||||
about: Use this when you have a question
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Question**
|
@ -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);
|
||||
@ -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;
|
||||
@ -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);
|
||||
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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]
|
||||
@ -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')
|
||||
"
|
||||
);
|
||||
|
@ -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);
|
||||
}"
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user