diff --git a/Cargo.lock b/Cargo.lock index 34c87d5633286..fa1a904ba9a1b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1560,10 +1560,14 @@ name = "oxc_mangler" version = "0.20.0" dependencies = [ "itertools 0.13.0", + "oxc_allocator", "oxc_ast", + "oxc_codegen", "oxc_index", + "oxc_parser", "oxc_semantic", "oxc_span", + "pico-args", ] [[package]] diff --git a/crates/oxc_mangler/Cargo.toml b/crates/oxc_mangler/Cargo.toml index 197986ba3cadb..307d7abb0b7d6 100644 --- a/crates/oxc_mangler/Cargo.toml +++ b/crates/oxc_mangler/Cargo.toml @@ -26,3 +26,9 @@ oxc_ast = { workspace = true } oxc_semantic = { workspace = true } oxc_index = { workspace = true } itertools = { workspace = true } + +[dev-dependencies] +oxc_allocator = { workspace = true } +oxc_parser = { workspace = true } +oxc_codegen = { workspace = true } +pico-args = { workspace = true } diff --git a/crates/oxc_mangler/examples/mangler.rs b/crates/oxc_mangler/examples/mangler.rs new file mode 100644 index 0000000000000..775636ef16f08 --- /dev/null +++ b/crates/oxc_mangler/examples/mangler.rs @@ -0,0 +1,43 @@ +#![allow(clippy::print_stdout)] +use std::path::Path; + +use oxc_allocator::Allocator; +use oxc_codegen::CodeGenerator; +use oxc_mangler::ManglerBuilder; +use oxc_parser::Parser; +use oxc_span::SourceType; +use pico_args::Arguments; + +// Instruction: +// create a `test.js`, +// run `cargo run -p oxc_mangler --example mangler` or `just example mangler` + +fn main() -> std::io::Result<()> { + let mut args = Arguments::from_env(); + + let name = args.subcommand().ok().flatten().unwrap_or_else(|| String::from("test.js")); + let debug = args.contains("--debug"); + let twice = args.contains("--twice"); + + let path = Path::new(&name); + let source_text = std::fs::read_to_string(path)?; + let source_type = SourceType::from_path(path).unwrap(); + + let printed = mangler(&source_text, source_type, debug); + println!("{printed}"); + + if twice { + let printed = mangler(&printed, source_type, debug); + println!("{printed}"); + } + + Ok(()) +} + +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); + CodeGenerator::new().with_mangler(Some(mangler)).build(program).source_text +} diff --git a/crates/oxc_mangler/src/lib.rs b/crates/oxc_mangler/src/lib.rs index 1918ddad3a40c..98e3ae1b3294e 100644 --- a/crates/oxc_mangler/src/lib.rs +++ b/crates/oxc_mangler/src/lib.rs @@ -63,9 +63,18 @@ impl Mangler { /// } /// } /// ``` -pub struct ManglerBuilder; +#[derive(Debug, Default)] +pub struct ManglerBuilder { + debug: bool, +} impl ManglerBuilder { + #[must_use] + pub fn debug(mut self, yes: bool) -> Self { + self.debug = yes; + self + } + #[must_use] pub fn build<'a>(self, program: &'a Program<'a>) -> Mangler { let semantic_ret = SemanticBuilder::new("", program.source_type).build(program); @@ -119,10 +128,11 @@ impl ManglerBuilder { let mut names = Vec::with_capacity(total_number_of_slots); + let generate_name = if self.debug { debug_name } else { base54 }; let mut count = 0; for _ in 0..total_number_of_slots { names.push(loop { - let name = base54(count); + let name = generate_name(count); count += 1; // Do not mangle keywords and unresolved references if !is_keyword(&name) && !unresolved_references.iter().any(|n| **n == name) { @@ -236,3 +246,7 @@ fn base54(n: usize) -> CompactStr { } CompactStr::new(&ret) } + +fn debug_name(n: usize) -> CompactStr { + CompactStr::from(format!("slot_{n}")) +} diff --git a/crates/oxc_minifier/src/lib.rs b/crates/oxc_minifier/src/lib.rs index 45bd7e278ce9b..16012ace41bdb 100644 --- a/crates/oxc_minifier/src/lib.rs +++ b/crates/oxc_minifier/src/lib.rs @@ -41,7 +41,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.build(program)); + let mangler = self.options.mangle.then(|| ManglerBuilder::default().build(program)); MinifierReturn { mangler } } }