refactor(minifier): expose dce as an API instead of an option (#7957)

This commit is contained in:
Boshen 2024-12-17 04:47:13 +00:00
parent 18441afe1c
commit 1314c9763b
5 changed files with 45 additions and 23 deletions

View file

@ -198,8 +198,12 @@ pub trait CompilerInterface {
if let Some(options) = define_options {
let ret =
ReplaceGlobalDefines::new(&allocator, options).build(symbols, scopes, &mut program);
Compressor::new(&allocator, CompressOptions::dead_code_elimination())
.build_with_symbols_and_scopes(ret.symbols, ret.scopes, &mut program);
Compressor::new(&allocator, CompressOptions::default())
.dead_code_elimination_with_symbols_and_scopes(
ret.symbols,
ret.scopes,
&mut program,
);
// symbols = ret.symbols;
// scopes = ret.scopes;
}

View file

@ -35,20 +35,30 @@ impl<'a> Compressor<'a> {
) {
let mut ctx = ReusableTraverseCtx::new(scopes, symbols, self.allocator);
RemoveSyntax::new(self.options).build(program, &mut ctx);
if self.options.dead_code_elimination {
Self::dead_code_elimination(program, &mut ctx);
return;
}
PeepholeOptimizations::new().build(program, &mut ctx);
CollapsePass::new().build(program, &mut ctx);
LatePeepholeOptimizations::new().run_in_loop(program, &mut ctx);
PeepholeOptimizations::new().build(program, &mut ctx);
}
fn dead_code_elimination(program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>) {
PeepholeFoldConstants::new().build(program, ctx);
PeepholeRemoveDeadCode::new().build(program, ctx);
pub fn dead_code_elimination(self, program: &mut Program<'a>) {
let (symbols, scopes) =
SemanticBuilder::new().build(program).semantic.into_symbol_table_and_scope_tree();
let mut ctx = ReusableTraverseCtx::new(scopes, symbols, self.allocator);
RemoveSyntax::new(self.options).build(program, &mut ctx);
PeepholeFoldConstants::new().build(program, &mut ctx);
PeepholeRemoveDeadCode::new().build(program, &mut ctx);
}
pub fn dead_code_elimination_with_symbols_and_scopes(
self,
symbols: SymbolTable,
scopes: ScopeTree,
program: &mut Program<'a>,
) {
let mut ctx = ReusableTraverseCtx::new(scopes, symbols, self.allocator);
RemoveSyntax::new(self.options).build(program, &mut ctx);
PeepholeFoldConstants::new().build(program, &mut ctx);
PeepholeRemoveDeadCode::new().build(program, &mut ctx);
}
}

View file

@ -1,7 +1,5 @@
#[derive(Debug, Clone, Copy)]
pub struct CompressOptions {
pub dead_code_elimination: bool,
/// Remove `debugger;` statements.
///
/// Default `true`
@ -16,20 +14,16 @@ pub struct CompressOptions {
#[allow(clippy::derivable_impls)]
impl Default for CompressOptions {
fn default() -> Self {
Self { dead_code_elimination: false, drop_console: false, ..Self::all_true() }
Self { drop_console: false, ..Self::all_true() }
}
}
impl CompressOptions {
pub fn all_true() -> Self {
Self { dead_code_elimination: false, drop_debugger: true, drop_console: true }
Self { drop_debugger: true, drop_console: true }
}
pub fn all_false() -> Self {
Self { dead_code_elimination: false, drop_debugger: false, drop_console: false }
}
pub fn dead_code_elimination() -> Self {
Self { dead_code_elimination: true, ..Self::all_false() }
Self { drop_debugger: false, drop_console: false }
}
}

View file

@ -1,6 +1,19 @@
use cow_utils::CowUtils;
use oxc_allocator::Allocator;
use oxc_codegen::Codegen;
use oxc_minifier::CompressOptions;
use oxc_minifier::Compressor;
use oxc_parser::Parser;
use oxc_span::SourceType;
fn run(source_text: &str, source_type: SourceType) -> String {
let allocator = Allocator::default();
let mut ret = Parser::new(&allocator, source_text, source_type).parse();
let program = &mut ret.program;
Compressor::new(&allocator, CompressOptions::default()).dead_code_elimination(program);
Codegen::new().build(program).code
}
fn test(source_text: &str, expected: &str) {
let t = "('production' == 'production')";
@ -8,8 +21,10 @@ fn test(source_text: &str, expected: &str) {
let source_text = source_text.cow_replace("true", t);
let source_text = source_text.cow_replace("false", f);
let options = CompressOptions::dead_code_elimination();
crate::test(&source_text, expected, options);
let source_type = SourceType::default();
let result = run(&source_text, source_type);
let expected = run(expected, source_type);
assert_eq!(result, expected, "\nfor source\n{source_text}\nexpect\n{expected}\ngot\n{result}");
}
fn test_same(source_text: &str) {

View file

@ -274,7 +274,6 @@ impl Oxc {
CompressOptions {
drop_console: compress_options.drop_console,
drop_debugger: compress_options.drop_debugger,
..CompressOptions::default()
}
} else {
CompressOptions::all_false()