mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
fix(minifier): drop debugger statements in unbraced bodies (#27867)
Replace debugger statements with empty statements during normalization so `dropDebugger` also removes them from unbraced `if`/`else`, loop, and labeled bodies. Add regressions covering these positions, preserved side effects, and `dropDebugger: false`. Fixes #27866
This commit is contained in:
1 parent
4661bf0230
commit
d92789d0c7
3 files changed
+34
-7
No files matched your search
@@ -101,15 +101,11 @@ impl<'a> Traverse<'a> for Normalize {
|
||||
fn exit_statements(
|
||||
&mut self,
|
||||
stmts: &mut ArenaVec<'a, Statement<'a>>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
_ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
// No console handling here: `exit_expression` has already rewritten
|
||||
// every console call (statement position included) to `void 0`.
|
||||
stmts.retain(|stmt| match stmt {
|
||||
Statement::EmptyStatement(_) => false,
|
||||
Statement::DebuggerStatement(_) if ctx.options().drop_debugger => false,
|
||||
_ => true,
|
||||
});
|
||||
stmts.retain(|stmt| !matches!(stmt, Statement::EmptyStatement(_)));
|
||||
}
|
||||
|
||||
fn exit_variable_declaration(
|
||||
@@ -124,6 +120,10 @@ impl<'a> Traverse<'a> for Normalize {
|
||||
|
||||
fn exit_statement(&mut self, stmt: &mut Statement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
match stmt {
|
||||
Statement::DebuggerStatement(debugger) if ctx.options().drop_debugger => {
|
||||
let new_stmt = Statement::new_empty_statement(debugger.span, ctx);
|
||||
ctx.replace_statement(stmt, new_stmt);
|
||||
}
|
||||
Statement::WhileStatement(_) if self.options.convert_while_to_fors => {
|
||||
Self::convert_while_to_for(stmt, ctx);
|
||||
}
|
||||
|
||||
@@ -78,7 +78,34 @@ fn drop_console_does_not_leak_references() {
|
||||
#[test]
|
||||
fn drop_debugger() {
|
||||
let options = CompressOptions { drop_debugger: true, ..default_options() };
|
||||
|
||||
test_options("debugger", "", &options);
|
||||
test_options(
|
||||
"export function f(x) { debugger; if (x) debugger; return x }",
|
||||
"export function f(x) { return x }",
|
||||
&options,
|
||||
);
|
||||
test_options(
|
||||
"export function f(x) { debugger; if (x) { debugger; } return x }",
|
||||
"export function f(x) { return x }",
|
||||
&options,
|
||||
);
|
||||
test_options("if (foo()) debugger", "foo()", &options);
|
||||
test_options("if (x) debugger; else foo()", "x || foo()", &options);
|
||||
test_options("if (x) foo(); else debugger", "x && foo()", &options);
|
||||
test_options("while (foo()) debugger", "for (; foo(););", &options);
|
||||
test_options("do debugger; while (foo())", "do; while (foo());", &options);
|
||||
test_options("for (foo(); bar(); baz()) debugger", "for (foo(); bar(); baz());", &options);
|
||||
test_options("for (var x in foo()) debugger", "for (var x in foo());", &options);
|
||||
test_options("for (var x of foo()) debugger", "for (var x of foo());", &options);
|
||||
test_options("label: debugger", "", &options);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn keep_debugger() {
|
||||
test_same("export function f(x) { debugger; if (x) debugger; return x }");
|
||||
test_same("if (x) debugger; else debugger;");
|
||||
test_same("for (; foo();) debugger;");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -71,6 +71,6 @@ kitchen-sink.tsx:
|
||||
sys deallocs: 1854
|
||||
sys alloc bytes: 5304252 # 5.30 MB
|
||||
sys peak growth: 3707425 # 3.71 MB
|
||||
arena allocs: 31111
|
||||
arena allocs: 31112
|
||||
arena reallocs: 3012
|
||||
arena size: 8461040 # 8.46 MB
|
||||
Reference in new issue
Block a user