Skip to content

Commit 3ef980a

Browse files
committed
feat(minifier): remove unreachable statements after break and continue (#8743)
1 parent e00e3ab commit 3ef980a

File tree

1 file changed

+22
-5
lines changed

1 file changed

+22
-5
lines changed

crates/oxc_minifier/src/peephole/remove_dead_code.rs

+22-5
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ impl<'a, 'b> PeepholeOptimizations {
2323
stmts: &mut Vec<'a, Statement<'a>>,
2424
ctx: Ctx<'a, '_>,
2525
) {
26+
self.dead_code_elimination(stmts, ctx);
2627
if stmts.iter().any(|stmt| matches!(stmt, Statement::EmptyStatement(_))) {
2728
stmts.retain(|stmt| !matches!(stmt, Statement::EmptyStatement(_)));
2829
}
29-
self.dead_code_elimination(stmts, ctx);
3030
}
3131

3232
pub fn remove_dead_code_exit_statement(&mut self, stmt: &mut Statement<'a>, ctx: Ctx<'a, '_>) {
@@ -68,20 +68,19 @@ impl<'a, 'b> PeepholeOptimizations {
6868
}
6969
}
7070

71-
/// Removes dead code thats comes after `return` statements after inlining `if` statements
71+
/// Removes dead code thats comes after `return`, `throw`, `continue` and `break` statements.
7272
fn dead_code_elimination(&mut self, stmts: &mut Vec<'a, Statement<'a>>, ctx: Ctx<'a, 'b>) {
7373
// Remove code after `return` and `throw` statements
7474
let mut index = None;
7575
'outer: for (i, stmt) in stmts.iter().enumerate() {
76-
if matches!(stmt, Statement::ReturnStatement(_) | Statement::ThrowStatement(_)) {
76+
if Self::is_unreachable_statement(stmt) {
7777
index.replace(i);
7878
break;
7979
}
8080
// Double check block statements folded by if statements above
8181
if let Statement::BlockStatement(block_stmt) = stmt {
8282
for stmt in &block_stmt.body {
83-
if matches!(stmt, Statement::ReturnStatement(_) | Statement::ThrowStatement(_))
84-
{
83+
if Self::is_unreachable_statement(stmt) {
8584
index.replace(i);
8685
break 'outer;
8786
}
@@ -129,6 +128,16 @@ impl<'a, 'b> PeepholeOptimizations {
129128
}
130129
}
131130

131+
fn is_unreachable_statement(stmt: &Statement<'a>) -> bool {
132+
matches!(
133+
stmt,
134+
Statement::ReturnStatement(_)
135+
| Statement::ThrowStatement(_)
136+
| Statement::BreakStatement(_)
137+
| Statement::ContinueStatement(_)
138+
)
139+
}
140+
132141
/// Remove block from single line blocks
133142
/// `{ block } -> block`
134143
fn try_optimize_block(
@@ -915,4 +924,12 @@ mod test {
915924
test("foo(...[])", "foo()");
916925
test("new Foo(...[])", "new Foo()");
917926
}
927+
928+
#[test]
929+
fn remove_unreachable() {
930+
test("while(true) { break a; unreachable;}", "for(;;) break a");
931+
test("while(true) { continue a; unreachable;}", "for(;;) continue a");
932+
test("while(true) { throw a; unreachable;}", "for(;;) throw a");
933+
test("while(true) { return a; unreachable;}", "for(;;) return a");
934+
}
918935
}

0 commit comments

Comments
 (0)