From ee80f63b27a678d61a10f03bd15bdbf575c8baa8 Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Sun, 29 Dec 2024 13:53:47 +0900 Subject: [PATCH] fix(minifier): move drop_use_strict_directives_if_function_is_empty to PeepholeRemoveDeadCode --- crates/oxc_minifier/src/ast_passes/mod.rs | 9 +++++++++ .../ast_passes/peephole_remove_dead_code.rs | 19 +++++++++++++++++++ .../src/ast_passes/remove_syntax.rs | 16 ---------------- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/crates/oxc_minifier/src/ast_passes/mod.rs b/crates/oxc_minifier/src/ast_passes/mod.rs index 459265a14fe03..99dc063b5f8d6 100644 --- a/crates/oxc_minifier/src/ast_passes/mod.rs +++ b/crates/oxc_minifier/src/ast_passes/mod.rs @@ -146,6 +146,7 @@ impl<'a> Traverse<'a> for LatePeepholeOptimizations { fn exit_function_body(&mut self, body: &mut FunctionBody<'a>, ctx: &mut TraverseCtx<'a>) { self.x0_statement_fusion.exit_function_body(body, ctx); + self.x2_peephole_remove_dead_code.exit_function_body(body, ctx); } fn exit_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, ctx: &mut TraverseCtx<'a>) { @@ -232,6 +233,10 @@ impl<'a> Traverse<'a> for PeepholeOptimizations { self.x5_peephole_remove_dead_code.exit_program(program, ctx); } + fn exit_function_body(&mut self, body: &mut FunctionBody<'a>, ctx: &mut TraverseCtx<'a>) { + self.x5_peephole_remove_dead_code.exit_function_body(body, ctx); + } + fn exit_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, ctx: &mut TraverseCtx<'a>) { self.x2_peephole_minimize_conditions.exit_statements(stmts, ctx); self.x5_peephole_remove_dead_code.exit_statements(stmts, ctx); @@ -300,6 +305,10 @@ impl<'a> Traverse<'a> for DeadCodeElimination { self.x2_peephole_remove_dead_code.exit_program(program, ctx); } + fn exit_function_body(&mut self, body: &mut FunctionBody<'a>, ctx: &mut TraverseCtx<'a>) { + self.x2_peephole_remove_dead_code.exit_function_body(body, ctx); + } + fn exit_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, ctx: &mut TraverseCtx<'a>) { self.x2_peephole_remove_dead_code.exit_statements(stmts, ctx); } diff --git a/crates/oxc_minifier/src/ast_passes/peephole_remove_dead_code.rs b/crates/oxc_minifier/src/ast_passes/peephole_remove_dead_code.rs index 18d23ed4b9353..0c66c0746cbda 100644 --- a/crates/oxc_minifier/src/ast_passes/peephole_remove_dead_code.rs +++ b/crates/oxc_minifier/src/ast_passes/peephole_remove_dead_code.rs @@ -24,6 +24,10 @@ impl<'a> CompressorPass<'a> for PeepholeRemoveDeadCode { } impl<'a> Traverse<'a> for PeepholeRemoveDeadCode { + fn exit_function_body(&mut self, body: &mut FunctionBody<'a>, ctx: &mut TraverseCtx<'a>) { + Self::drop_use_strict_directives_if_function_is_empty(body, ctx); + } + fn exit_statement(&mut self, stmt: &mut Statement<'a>, ctx: &mut TraverseCtx<'a>) { let ctx = Ctx(ctx); if let Some(new_stmt) = match stmt { @@ -124,6 +128,16 @@ impl<'a, 'b> PeepholeRemoveDeadCode { } } + /// Drop `"use strict";` directives if the function is empty. + fn drop_use_strict_directives_if_function_is_empty( + body: &mut FunctionBody<'a>, + _ctx: &mut TraverseCtx<'a>, + ) { + if body.statements.is_empty() { + body.directives.retain(|directive| !directive.is_use_strict()); + } + } + /// Remove block from single line blocks /// `{ block } -> block` fn try_optimize_block( @@ -436,6 +450,11 @@ mod test { test(js, expected); } + #[test] + fn use_strict() { + test("function foo() { 'use strict';}", "function foo() {}"); + } + #[test] fn test_fold_block() { fold("{{foo()}}", "foo()"); diff --git a/crates/oxc_minifier/src/ast_passes/remove_syntax.rs b/crates/oxc_minifier/src/ast_passes/remove_syntax.rs index 6682fad9347a7..b91d9d6b6beb4 100644 --- a/crates/oxc_minifier/src/ast_passes/remove_syntax.rs +++ b/crates/oxc_minifier/src/ast_passes/remove_syntax.rs @@ -29,10 +29,6 @@ impl<'a> Traverse<'a> for RemoveSyntax { Self::drop_use_strict_directives_in_function_body(body, ctx); } - fn exit_function_body(&mut self, body: &mut FunctionBody<'a>, ctx: &mut TraverseCtx<'a>) { - Self::drop_use_strict_directives_if_function_is_empty(body, ctx); - } - fn exit_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, _ctx: &mut TraverseCtx<'a>) { stmts.retain(|stmt| { !(matches!(stmt, Statement::EmptyStatement(_)) @@ -123,16 +119,6 @@ impl<'a> RemoveSyntax { body.directives.retain(|directive| !directive.is_use_strict()); } } - - /// Drop `"use strict";` directives if the function is empty. - fn drop_use_strict_directives_if_function_is_empty( - body: &mut FunctionBody<'a>, - _ctx: &mut TraverseCtx<'a>, - ) { - if body.statements.is_empty() { - body.directives.retain(|directive| !directive.is_use_strict()); - } - } } #[cfg(test)] @@ -205,7 +191,5 @@ mod test { "const Foo = class { foo() { 'use strict'; alert(1); } } ", "const Foo = class { foo() { alert(1); } } ", ); - - test_script("function foo() { 'use strict';}", "function foo() {}"); } }