diff --git a/crates/oxc/Cargo.toml b/crates/oxc/Cargo.toml index d19aabf5e..5ccdd2fe4 100644 --- a/crates/oxc/Cargo.toml +++ b/crates/oxc/Cargo.toml @@ -42,12 +42,13 @@ oxc_sourcemap = { workspace = true, optional = true } oxc_isolated_declarations = { workspace = true, optional = true } [features] -full = ["codegen", "minifier", "semantic", "transformer"] +full = ["codegen", "mangler", "minifier", "semantic", "transformer"] semantic = ["oxc_semantic"] transformer = ["oxc_transformer"] minifier = ["oxc_mangler", "oxc_minifier"] codegen = ["oxc_codegen"] +mangler = ["oxc_mangler"] serialize = ["oxc_ast/serialize", "oxc_semantic?/serialize", "oxc_span/serialize", "oxc_syntax/serialize"] diff --git a/crates/oxc/src/compiler.rs b/crates/oxc/src/compiler.rs index 131456e9e..a2d12ff44 100644 --- a/crates/oxc/src/compiler.rs +++ b/crates/oxc/src/compiler.rs @@ -4,6 +4,7 @@ use oxc_allocator::Allocator; use oxc_ast::{ast::Program, Trivias}; use oxc_codegen::{CodeGenerator, CodegenOptions, CommentOptions}; use oxc_diagnostics::OxcDiagnostic; +use oxc_mangler::{MangleOptions, Mangler}; use oxc_parser::{ParseOptions, Parser, ParserReturn}; use oxc_span::SourceType; @@ -49,7 +50,7 @@ impl Compiler { pub trait CompilerInterface { fn handle_errors(&mut self, _errors: Vec) {} - fn parser_options(&self) -> ParseOptions { + fn parse_options(&self) -> ParseOptions { ParseOptions::default() } @@ -61,6 +62,10 @@ pub trait CompilerInterface { None } + fn mangle_options(&self) -> Option { + None + } + fn codegen_options(&self) -> Option { Some(CodegenOptions::default()) } @@ -145,12 +150,20 @@ pub trait CompilerInterface { } } + /* Compress */ + if let Some(options) = self.compress_options() { self.compress(&allocator, &mut program, options); } + /* Mangler */ + + let mangler = self.mangle_options().map(|options| self.mangle(&mut program, options)); + + /* Codegen */ + if let Some(options) = self.codegen_options() { - let printed = self.codegen(&program, source_text, &trivias, options); + let printed = self.codegen(&program, source_text, &trivias, mangler, options); self.after_codegen(printed); } } @@ -161,7 +174,7 @@ pub trait CompilerInterface { source_text: &'a str, source_type: SourceType, ) -> ParserReturn<'a> { - Parser::new(allocator, source_text, source_type).with_options(self.parser_options()).parse() + Parser::new(allocator, source_text, source_type).with_options(self.parse_options()).parse() } fn semantic<'a>( @@ -203,16 +216,22 @@ pub trait CompilerInterface { Compressor::new(allocator, options).build(program); } + fn mangle(&self, program: &mut Program<'_>, options: MangleOptions) -> Mangler { + Mangler::new().with_options(options).build(program) + } + fn codegen<'a>( &self, program: &Program<'a>, source_text: &'a str, trivias: &Trivias, + mangler: Option, options: CodegenOptions, ) -> String { let comment_options = CommentOptions { preserve_annotate_comments: true }; CodeGenerator::new() .with_options(options) + .with_mangler(mangler) .enable_comment(source_text, trivias.clone(), comment_options) .build(program) .source_text diff --git a/crates/oxc/src/lib.rs b/crates/oxc/src/lib.rs index 7a72c18c0..0cc28b899 100644 --- a/crates/oxc/src/lib.rs +++ b/crates/oxc/src/lib.rs @@ -61,7 +61,7 @@ pub mod minifier { pub use oxc_minifier::*; } -#[cfg(feature = "minifier")] +#[cfg(feature = "mangler")] pub mod mangler { #[doc(inline)] pub use oxc_mangler::*; diff --git a/crates/oxc_mangler/src/lib.rs b/crates/oxc_mangler/src/lib.rs index 041bd1ed2..db75b5aed 100644 --- a/crates/oxc_mangler/src/lib.rs +++ b/crates/oxc_mangler/src/lib.rs @@ -6,20 +6,9 @@ use oxc_span::CompactStr; type Slot = usize; -#[derive(Debug)] -pub struct Mangler { - symbol_table: SymbolTable, -} - -impl Mangler { - pub fn get_symbol_name(&self, symbol_id: SymbolId) -> &str { - self.symbol_table.get_name(symbol_id) - } - - pub fn get_reference_name(&self, reference_id: ReferenceId) -> Option<&str> { - let symbol_id = self.symbol_table.get_reference(reference_id).symbol_id()?; - Some(self.symbol_table.get_name(symbol_id)) - } +#[derive(Default)] +pub struct MangleOptions { + pub debug: bool, } /// # Name Mangler / Symbol Minification @@ -63,20 +52,36 @@ impl Mangler { /// } /// } /// ``` -#[derive(Debug, Default)] -pub struct ManglerBuilder { - debug: bool, +#[derive(Default)] +pub struct Mangler { + symbol_table: SymbolTable, + + options: MangleOptions, } -impl ManglerBuilder { +impl Mangler { #[must_use] - pub fn debug(mut self, yes: bool) -> Self { - self.debug = yes; - self + pub fn new() -> Self { + Self::default() } #[must_use] - pub fn build<'a>(self, program: &'a Program<'a>) -> Mangler { + pub fn with_options(mut self, options: MangleOptions) -> Self { + self.options = options; + self + } + + pub fn get_symbol_name(&self, symbol_id: SymbolId) -> &str { + self.symbol_table.get_name(symbol_id) + } + + pub fn get_reference_name(&self, reference_id: ReferenceId) -> Option<&str> { + let symbol_id = self.symbol_table.get_reference(reference_id).symbol_id()?; + Some(self.symbol_table.get_name(symbol_id)) + } + + #[must_use] + pub fn build<'a>(mut self, program: &'a Program<'a>) -> Mangler { let semantic = SemanticBuilder::new("", program.source_type).build(program).semantic; // Mangle the symbol table by computing slots from the scope tree. @@ -123,7 +128,7 @@ impl ManglerBuilder { let mut names = Vec::with_capacity(total_number_of_slots); - let generate_name = if self.debug { debug_name } else { base54 }; + let generate_name = if self.options.debug { debug_name } else { base54 }; let mut count = 0; for _ in 0..total_number_of_slots { names.push(loop { @@ -182,7 +187,8 @@ impl ManglerBuilder { } } - Mangler { symbol_table } + self.symbol_table = symbol_table; + self } fn tally_slot_frequencies( diff --git a/crates/oxc_minifier/examples/mangler.rs b/crates/oxc_minifier/examples/mangler.rs index d0109334b..3e71995db 100644 --- a/crates/oxc_minifier/examples/mangler.rs +++ b/crates/oxc_minifier/examples/mangler.rs @@ -3,7 +3,7 @@ use std::path::Path; use oxc_allocator::Allocator; use oxc_codegen::CodeGenerator; -use oxc_mangler::ManglerBuilder; +use oxc_mangler::{MangleOptions, Mangler}; use oxc_parser::Parser; use oxc_span::SourceType; use pico_args::Arguments; @@ -39,6 +39,6 @@ fn mangler(source_text: &str, source_type: SourceType, debug: bool) -> String { let allocator = Allocator::default(); let ret = Parser::new(&allocator, source_text, source_type).parse(); let program = allocator.alloc(ret.program); - let mangler = ManglerBuilder::default().debug(debug).build(program); + let mangler = Mangler::new().with_options(MangleOptions { debug }).build(program); CodeGenerator::new().with_mangler(Some(mangler)).build(program).source_text } diff --git a/crates/oxc_minifier/src/lib.rs b/crates/oxc_minifier/src/lib.rs index d987a0d8d..b1320f7de 100644 --- a/crates/oxc_minifier/src/lib.rs +++ b/crates/oxc_minifier/src/lib.rs @@ -13,7 +13,7 @@ mod ty; use oxc_allocator::Allocator; use oxc_ast::ast::Program; -use oxc_mangler::{Mangler, ManglerBuilder}; +use oxc_mangler::Mangler; pub use crate::{ ast_passes::{CompressorPass, RemoveDeadCode, RemoveSyntax}, @@ -49,7 +49,7 @@ impl Minifier { pub fn build<'a>(self, allocator: &'a Allocator, program: &mut Program<'a>) -> MinifierReturn { Compressor::new(allocator, self.options.compress).build(program); - let mangler = self.options.mangle.then(|| ManglerBuilder::default().build(program)); + let mangler = self.options.mangle.then(|| Mangler::default().build(program)); MinifierReturn { mangler } } } diff --git a/crates/oxc_minifier/tests/mangler/mod.rs b/crates/oxc_minifier/tests/mangler/mod.rs index 471c1b86d..445431d04 100644 --- a/crates/oxc_minifier/tests/mangler/mod.rs +++ b/crates/oxc_minifier/tests/mangler/mod.rs @@ -2,7 +2,7 @@ use std::fmt::Write; use oxc_allocator::Allocator; use oxc_codegen::CodeGenerator; -use oxc_mangler::ManglerBuilder; +use oxc_mangler::Mangler; use oxc_parser::Parser; use oxc_span::SourceType; @@ -11,7 +11,7 @@ fn mangle(source_text: &str) -> String { let source_type = SourceType::default().with_module(true); let ret = Parser::new(&allocator, source_text, source_type).parse(); let program = ret.program; - let mangler = ManglerBuilder::default().build(&program); + let mangler = Mangler::new().build(&program); CodeGenerator::new().with_mangler(Some(mangler)).build(&program).source_text } diff --git a/tasks/coverage/src/driver.rs b/tasks/coverage/src/driver.rs index 8f329414c..28f247519 100644 --- a/tasks/coverage/src/driver.rs +++ b/tasks/coverage/src/driver.rs @@ -34,7 +34,7 @@ pub struct Driver { } impl CompilerInterface for Driver { - fn parser_options(&self) -> ParseOptions { + fn parse_options(&self) -> ParseOptions { ParseOptions { allow_return_outside_function: self.allow_return_outside_function, ..ParseOptions::default()