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
|
name: Bug report
|
||||||
about: Create a report to help us improve
|
about: Use this when swc breaks something
|
||||||
title: ''
|
title: ''
|
||||||
labels: C-bug
|
labels: C-bug
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: Crash report
|
name: Crash report
|
||||||
about: Create a report to help us improve
|
about: Use this when swc panics
|
||||||
title: 'panic: '
|
title: 'panic: '
|
||||||
labels: C-bug
|
labels: C-bug
|
||||||
assignees: ''
|
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<'_> {
|
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
|
where
|
||||||
F: FnOnce(&mut Self) -> Ret,
|
F: FnOnce(&mut Self),
|
||||||
{
|
{
|
||||||
self.leaps.push(entry);
|
self.leaps.push(entry);
|
||||||
let ret = op(self);
|
let ret = op(self);
|
||||||
@ -92,15 +92,20 @@ impl CaseHandler<'_> {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut last_loc_value = 0;
|
// let mut last_loc_value = 0;
|
||||||
Some(ArrayLit {
|
Some(ArrayLit {
|
||||||
span: DUMMY_SP,
|
span: DUMMY_SP,
|
||||||
elems: replace(&mut self.try_entries, Default::default())
|
elems: replace(&mut self.try_entries, Default::default())
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|entry: TryEntry| {
|
.map(|entry: TryEntry| {
|
||||||
let this_loc_value = entry.first_loc;
|
// let this_loc_value = entry.first_loc;
|
||||||
assert!(this_loc_value.stmt_index >= last_loc_value);
|
// assert!(
|
||||||
last_loc_value = this_loc_value.stmt_index;
|
// 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 ce = entry.catch_entry;
|
||||||
let fe = entry.finally_entry;
|
let fe = entry.finally_entry;
|
||||||
@ -1091,7 +1096,7 @@ impl CaseHandler<'_> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
self.update_ctx_prev_loc(Some(&mut try_entry.first_loc));
|
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| {
|
self.with_entry(Entry::TryEntry(try_entry.clone()), |folder| {
|
||||||
//
|
//
|
||||||
folder.explode_stmts(block.stmts);
|
folder.explode_stmts(block.stmts);
|
||||||
@ -1343,7 +1348,12 @@ impl CaseHandler<'_> {
|
|||||||
self.mark(after);
|
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 {
|
impl Fold<VarDeclOrExpr> for Hoister {
|
||||||
fn fold(&mut self, var: VarDeclOrExpr) -> VarDeclOrExpr {
|
fn fold(&mut self, var: VarDeclOrExpr) -> VarDeclOrExpr {
|
||||||
let var = var.fold_children(self);
|
|
||||||
|
|
||||||
match var {
|
match var {
|
||||||
VarDeclOrExpr::VarDecl(var) => VarDeclOrExpr::Expr(box self.var_decl_to_expr(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) {
|
pub fn push(&mut self, entry: Entry) {
|
||||||
self.stack.push(entry);
|
self.stack.push(entry);
|
||||||
}
|
}
|
||||||
pub fn pop(&mut self) {
|
pub fn pop(&mut self) -> Option<Entry> {
|
||||||
self.stack.pop();
|
self.stack.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_leap_loc<F>(&self, mut pred: F, label: Option<&JsWord>) -> Option<Loc>
|
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_common::chain;
|
||||||
use swc_ecma_parser::Syntax;
|
use swc_ecma_parser::Syntax;
|
||||||
use swc_ecma_transforms::{
|
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]
|
#[macro_use]
|
||||||
@ -965,3 +968,53 @@ expect(v.next()).toEqual({ value: 4, done: false });
|
|||||||
expect(v.next()).toEqual({ done: true });
|
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