oxc_minifier/
compressor.rs1use oxc_allocator::Allocator;
2use oxc_ast::ast::*;
3use oxc_semantic::{Scoping, SemanticBuilder};
4use oxc_traverse::ReusableTraverseCtx;
5
6use crate::{
7 CompressOptions,
8 peephole::{DeadCodeElimination, Normalize, NormalizeOptions, PeepholeOptimizations},
9 state::MinifierState,
10};
11
12pub struct Compressor<'a> {
13 allocator: &'a Allocator,
14}
15
16impl<'a> Compressor<'a> {
17 pub fn new(allocator: &'a Allocator) -> Self {
18 Self { allocator }
19 }
20
21 pub fn build(self, program: &mut Program<'a>, options: CompressOptions) {
22 let scoping = SemanticBuilder::new().build(program).semantic.into_scoping();
23 self.build_with_scoping(program, scoping, options);
24 }
25
26 pub fn build_with_scoping(
28 self,
29 program: &mut Program<'a>,
30 scoping: Scoping,
31 options: CompressOptions,
32 ) -> u8 {
33 let max_iterations = options.max_iterations;
34 let state = MinifierState::new(program.source_type, options);
35 let mut ctx = ReusableTraverseCtx::new(state, scoping, self.allocator);
36 let normalize_options = NormalizeOptions {
37 convert_while_to_fors: true,
38 convert_const_to_let: true,
39 remove_unnecessary_use_strict: true,
40 };
41 Normalize::new(normalize_options).build(program, &mut ctx);
42 PeepholeOptimizations::new(max_iterations).run_in_loop(program, &mut ctx)
43 }
44
45 pub fn dead_code_elimination(self, program: &mut Program<'a>, options: CompressOptions) -> u8 {
46 let scoping = SemanticBuilder::new().build(program).semantic.into_scoping();
47 self.dead_code_elimination_with_scoping(program, scoping, options)
48 }
49
50 pub fn dead_code_elimination_with_scoping(
52 self,
53 program: &mut Program<'a>,
54 scoping: Scoping,
55 options: CompressOptions,
56 ) -> u8 {
57 let max_iterations = options.max_iterations;
58 let state = MinifierState::new(program.source_type, options);
59 let mut ctx = ReusableTraverseCtx::new(state, scoping, self.allocator);
60 let normalize_options = NormalizeOptions {
61 convert_while_to_fors: false,
62 convert_const_to_let: false,
63 remove_unnecessary_use_strict: false,
64 };
65 Normalize::new(normalize_options).build(program, &mut ctx);
66 DeadCodeElimination::new(max_iterations).run_in_loop(program, &mut ctx)
67 }
68}