mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
refactor(minifier): improve ast passes (#7518)
This commit is contained in:
parent
32f860d238
commit
625a5bad02
12 changed files with 145 additions and 127 deletions
|
|
@ -9,14 +9,10 @@ use crate::CompressorPass;
|
||||||
/// `var a; var b = 1; var c = 2` => `var a, b = 1; c = 2`
|
/// `var a; var b = 1; var c = 2` => `var a, b = 1; c = 2`
|
||||||
/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/CollapseVariableDeclarations.java>
|
/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/CollapseVariableDeclarations.java>
|
||||||
pub struct CollapseVariableDeclarations {
|
pub struct CollapseVariableDeclarations {
|
||||||
changed: bool,
|
pub(crate) changed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CompressorPass<'a> for CollapseVariableDeclarations {
|
impl<'a> CompressorPass<'a> for CollapseVariableDeclarations {
|
||||||
fn changed(&self) -> bool {
|
|
||||||
self.changed
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build(&mut self, program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>) {
|
fn build(&mut self, program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>) {
|
||||||
self.changed = false;
|
self.changed = false;
|
||||||
traverse_mut_with_ctx(self, program, ctx);
|
traverse_mut_with_ctx(self, program, ctx);
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,10 @@ use crate::CompressorPass;
|
||||||
///
|
///
|
||||||
/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/ExploitAssigns.java>
|
/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/ExploitAssigns.java>
|
||||||
pub struct ExploitAssigns {
|
pub struct ExploitAssigns {
|
||||||
changed: bool,
|
pub(crate) changed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CompressorPass<'a> for ExploitAssigns {
|
impl<'a> CompressorPass<'a> for ExploitAssigns {
|
||||||
fn changed(&self) -> bool {
|
|
||||||
self.changed
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build(&mut self, program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>) {
|
fn build(&mut self, program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>) {
|
||||||
self.changed = false;
|
self.changed = false;
|
||||||
traverse_mut_with_ctx(self, program, ctx);
|
traverse_mut_with_ctx(self, program, ctx);
|
||||||
|
|
|
||||||
|
|
@ -23,13 +23,46 @@ use oxc_ast::ast::*;
|
||||||
use oxc_traverse::{traverse_mut_with_ctx, ReusableTraverseCtx, Traverse, TraverseCtx};
|
use oxc_traverse::{traverse_mut_with_ctx, ReusableTraverseCtx, Traverse, TraverseCtx};
|
||||||
|
|
||||||
pub trait CompressorPass<'a>: Traverse<'a> {
|
pub trait CompressorPass<'a>: Traverse<'a> {
|
||||||
fn changed(&self) -> bool;
|
|
||||||
|
|
||||||
fn build(&mut self, program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>);
|
fn build(&mut self, program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See `peepholeOptimizationsOnce`
|
||||||
|
|
||||||
|
// For pass:
|
||||||
|
// ```
|
||||||
|
// if (options.collapseVariableDeclarations) {
|
||||||
|
// passes.maybeAdd(exploitAssign);
|
||||||
|
// passes.maybeAdd(collapseVariableDeclarations);
|
||||||
|
// }
|
||||||
|
// ```
|
||||||
|
pub struct CollapsePass {
|
||||||
|
_x0_exploit_assigns: ExploitAssigns,
|
||||||
|
x1_collapse_variable_declarations: CollapseVariableDeclarations,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CollapsePass {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
_x0_exploit_assigns: ExploitAssigns::new(),
|
||||||
|
x1_collapse_variable_declarations: CollapseVariableDeclarations::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> CompressorPass<'a> for CollapsePass {
|
||||||
|
fn build(&mut self, program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>) {
|
||||||
|
traverse_mut_with_ctx(self, program, ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Traverse<'a> for CollapsePass {
|
||||||
|
fn enter_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, ctx: &mut TraverseCtx<'a>) {
|
||||||
|
self.x1_collapse_variable_declarations.enter_statements(stmts, ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// See `latePeepholeOptimizations`
|
// See `latePeepholeOptimizations`
|
||||||
pub struct EarlyPass {
|
pub struct LatePeepholeOptimizations {
|
||||||
x0_statement_fusion: StatementFusion,
|
x0_statement_fusion: StatementFusion,
|
||||||
x1_peephole_remove_dead_code: PeepholeRemoveDeadCode,
|
x1_peephole_remove_dead_code: PeepholeRemoveDeadCode,
|
||||||
// TODO: MinimizeExitPoints
|
// TODO: MinimizeExitPoints
|
||||||
|
|
@ -37,10 +70,9 @@ pub struct EarlyPass {
|
||||||
x3_peephole_substitute_alternate_syntax: PeepholeSubstituteAlternateSyntax,
|
x3_peephole_substitute_alternate_syntax: PeepholeSubstituteAlternateSyntax,
|
||||||
x4_peephole_replace_known_methods: PeepholeReplaceKnownMethods,
|
x4_peephole_replace_known_methods: PeepholeReplaceKnownMethods,
|
||||||
x5_peephole_fold_constants: PeepholeFoldConstants,
|
x5_peephole_fold_constants: PeepholeFoldConstants,
|
||||||
changed: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EarlyPass {
|
impl LatePeepholeOptimizations {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
x0_statement_fusion: StatementFusion::new(),
|
x0_statement_fusion: StatementFusion::new(),
|
||||||
|
|
@ -51,29 +83,55 @@ impl EarlyPass {
|
||||||
),
|
),
|
||||||
x4_peephole_replace_known_methods: PeepholeReplaceKnownMethods::new(),
|
x4_peephole_replace_known_methods: PeepholeReplaceKnownMethods::new(),
|
||||||
x5_peephole_fold_constants: PeepholeFoldConstants::new(),
|
x5_peephole_fold_constants: PeepholeFoldConstants::new(),
|
||||||
changed: false,
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reset_changed(&mut self) {
|
||||||
|
self.x0_statement_fusion.changed = false;
|
||||||
|
self.x1_peephole_remove_dead_code.changed = false;
|
||||||
|
self.x2_peephole_minimize_conditions.changed = false;
|
||||||
|
self.x3_peephole_substitute_alternate_syntax.changed = false;
|
||||||
|
self.x4_peephole_replace_known_methods.changed = false;
|
||||||
|
self.x5_peephole_fold_constants.changed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn changed(&self) -> bool {
|
||||||
|
self.x0_statement_fusion.changed
|
||||||
|
|| self.x1_peephole_remove_dead_code.changed
|
||||||
|
|| self.x2_peephole_minimize_conditions.changed
|
||||||
|
|| self.x3_peephole_substitute_alternate_syntax.changed
|
||||||
|
|| self.x4_peephole_replace_known_methods.changed
|
||||||
|
|| self.x5_peephole_fold_constants.changed
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run_in_loop<'a>(
|
||||||
|
&mut self,
|
||||||
|
program: &mut Program<'a>,
|
||||||
|
ctx: &mut ReusableTraverseCtx<'a>,
|
||||||
|
) {
|
||||||
|
let mut i = 0;
|
||||||
|
loop {
|
||||||
|
self.reset_changed();
|
||||||
|
self.build(program, ctx);
|
||||||
|
if !self.changed() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if i > 10 {
|
||||||
|
debug_assert!(false, "Ran loop more than 10 times.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CompressorPass<'a> for EarlyPass {
|
impl<'a> CompressorPass<'a> for LatePeepholeOptimizations {
|
||||||
fn changed(&self) -> bool {
|
|
||||||
self.changed
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build(&mut self, program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>) {
|
fn build(&mut self, program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>) {
|
||||||
self.changed = false;
|
|
||||||
traverse_mut_with_ctx(self, program, ctx);
|
traverse_mut_with_ctx(self, program, ctx);
|
||||||
self.changed = self.x0_statement_fusion.changed()
|
|
||||||
|| self.x1_peephole_remove_dead_code.changed()
|
|
||||||
|| self.x2_peephole_minimize_conditions.changed()
|
|
||||||
|| self.x3_peephole_substitute_alternate_syntax.changed()
|
|
||||||
|| self.x4_peephole_replace_known_methods.changed()
|
|
||||||
|| self.x5_peephole_fold_constants.changed();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Traverse<'a> for EarlyPass {
|
impl<'a> Traverse<'a> for LatePeepholeOptimizations {
|
||||||
fn enter_statement(&mut self, stmt: &mut Statement<'a>, ctx: &mut TraverseCtx<'a>) {
|
fn enter_statement(&mut self, stmt: &mut Statement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||||
self.x1_peephole_remove_dead_code.enter_statement(stmt, ctx);
|
self.x1_peephole_remove_dead_code.enter_statement(stmt, ctx);
|
||||||
}
|
}
|
||||||
|
|
@ -141,49 +199,56 @@ impl<'a> Traverse<'a> for EarlyPass {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Passes listed in `getFinalization` in `DefaultPassConfig`
|
// See `createPeepholeOptimizationsPass`
|
||||||
pub struct LatePass {
|
pub struct PeepholeOptimizations {
|
||||||
x0_exploit_assigns: ExploitAssigns,
|
// TODO: MinimizeExitPoints
|
||||||
x1_collapse_variable_declarations: CollapseVariableDeclarations,
|
x2_peephole_minimize_conditions: PeepholeMinimizeConditions,
|
||||||
x2_peephole_substitute_alternate_syntax: PeepholeSubstituteAlternateSyntax,
|
x3_peephole_substitute_alternate_syntax: PeepholeSubstituteAlternateSyntax,
|
||||||
changed: bool,
|
x4_peephole_replace_known_methods: PeepholeReplaceKnownMethods,
|
||||||
|
x5_peephole_remove_dead_code: PeepholeRemoveDeadCode,
|
||||||
|
x6_peephole_fold_constants: PeepholeFoldConstants,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LatePass {
|
impl PeepholeOptimizations {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
x0_exploit_assigns: ExploitAssigns::new(),
|
x2_peephole_minimize_conditions: PeepholeMinimizeConditions::new(),
|
||||||
x1_collapse_variable_declarations: CollapseVariableDeclarations::new(),
|
x3_peephole_substitute_alternate_syntax: PeepholeSubstituteAlternateSyntax::new(
|
||||||
x2_peephole_substitute_alternate_syntax: PeepholeSubstituteAlternateSyntax::new(
|
|
||||||
/* in_fixed_loop */ false,
|
/* in_fixed_loop */ false,
|
||||||
),
|
),
|
||||||
changed: false,
|
x4_peephole_replace_known_methods: PeepholeReplaceKnownMethods::new(),
|
||||||
|
x5_peephole_remove_dead_code: PeepholeRemoveDeadCode::new(),
|
||||||
|
x6_peephole_fold_constants: PeepholeFoldConstants::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CompressorPass<'a> for LatePass {
|
impl<'a> CompressorPass<'a> for PeepholeOptimizations {
|
||||||
fn changed(&self) -> bool {
|
|
||||||
self.changed
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build(&mut self, program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>) {
|
fn build(&mut self, program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>) {
|
||||||
self.changed = false;
|
|
||||||
traverse_mut_with_ctx(self, program, ctx);
|
traverse_mut_with_ctx(self, program, ctx);
|
||||||
self.changed = self.x0_exploit_assigns.changed()
|
|
||||||
|| self.x0_exploit_assigns.changed()
|
|
||||||
|| self.x1_collapse_variable_declarations.changed()
|
|
||||||
|| self.x2_peephole_substitute_alternate_syntax.changed();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Traverse<'a> for LatePass {
|
impl<'a> Traverse<'a> for PeepholeOptimizations {
|
||||||
fn enter_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, ctx: &mut TraverseCtx<'a>) {
|
fn enter_statement(&mut self, stmt: &mut Statement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||||
self.x1_collapse_variable_declarations.enter_statements(stmts, ctx);
|
self.x5_peephole_remove_dead_code.enter_statement(stmt, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn exit_statement(&mut self, stmt: &mut Statement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||||
|
self.x2_peephole_minimize_conditions.exit_statement(stmt, ctx);
|
||||||
|
self.x5_peephole_remove_dead_code.exit_statement(stmt, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn exit_program(&mut self, program: &mut Program<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||||
|
self.x5_peephole_remove_dead_code.exit_program(program, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn exit_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, ctx: &mut TraverseCtx<'a>) {
|
||||||
|
self.x5_peephole_remove_dead_code.exit_statements(stmts, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exit_return_statement(&mut self, stmt: &mut ReturnStatement<'a>, ctx: &mut TraverseCtx<'a>) {
|
fn exit_return_statement(&mut self, stmt: &mut ReturnStatement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||||
self.x2_peephole_substitute_alternate_syntax.exit_return_statement(stmt, ctx);
|
self.x3_peephole_substitute_alternate_syntax.exit_return_statement(stmt, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enter_variable_declaration(
|
fn enter_variable_declaration(
|
||||||
|
|
@ -191,23 +256,27 @@ impl<'a> Traverse<'a> for LatePass {
|
||||||
decl: &mut VariableDeclaration<'a>,
|
decl: &mut VariableDeclaration<'a>,
|
||||||
ctx: &mut TraverseCtx<'a>,
|
ctx: &mut TraverseCtx<'a>,
|
||||||
) {
|
) {
|
||||||
self.x2_peephole_substitute_alternate_syntax.enter_variable_declaration(decl, ctx);
|
self.x3_peephole_substitute_alternate_syntax.enter_variable_declaration(decl, ctx);
|
||||||
}
|
|
||||||
|
|
||||||
fn enter_call_expression(&mut self, expr: &mut CallExpression<'a>, ctx: &mut TraverseCtx<'a>) {
|
|
||||||
self.x2_peephole_substitute_alternate_syntax.enter_call_expression(expr, ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn exit_call_expression(&mut self, expr: &mut CallExpression<'a>, ctx: &mut TraverseCtx<'a>) {
|
|
||||||
self.x2_peephole_substitute_alternate_syntax.exit_call_expression(expr, ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enter_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
fn enter_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||||
self.x2_peephole_substitute_alternate_syntax.enter_expression(expr, ctx);
|
self.x3_peephole_substitute_alternate_syntax.enter_expression(expr, ctx);
|
||||||
|
self.x4_peephole_replace_known_methods.enter_expression(expr, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exit_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
fn exit_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||||
self.x2_peephole_substitute_alternate_syntax.exit_expression(expr, ctx);
|
self.x2_peephole_minimize_conditions.exit_expression(expr, ctx);
|
||||||
|
self.x3_peephole_substitute_alternate_syntax.exit_expression(expr, ctx);
|
||||||
|
self.x5_peephole_remove_dead_code.exit_expression(expr, ctx);
|
||||||
|
self.x6_peephole_fold_constants.exit_expression(expr, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn enter_call_expression(&mut self, expr: &mut CallExpression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||||
|
self.x3_peephole_substitute_alternate_syntax.enter_call_expression(expr, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn exit_call_expression(&mut self, expr: &mut CallExpression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||||
|
self.x3_peephole_substitute_alternate_syntax.exit_call_expression(expr, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enter_binary_expression(
|
fn enter_binary_expression(
|
||||||
|
|
@ -215,6 +284,6 @@ impl<'a> Traverse<'a> for LatePass {
|
||||||
expr: &mut BinaryExpression<'a>,
|
expr: &mut BinaryExpression<'a>,
|
||||||
ctx: &mut TraverseCtx<'a>,
|
ctx: &mut TraverseCtx<'a>,
|
||||||
) {
|
) {
|
||||||
self.x2_peephole_substitute_alternate_syntax.enter_binary_expression(expr, ctx);
|
self.x3_peephole_substitute_alternate_syntax.enter_binary_expression(expr, ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,14 +16,10 @@ use crate::{node_util::Ctx, CompressorPass};
|
||||||
///
|
///
|
||||||
/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/PeepholeFoldConstants.java>
|
/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/PeepholeFoldConstants.java>
|
||||||
pub struct PeepholeFoldConstants {
|
pub struct PeepholeFoldConstants {
|
||||||
changed: bool,
|
pub(crate) changed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CompressorPass<'a> for PeepholeFoldConstants {
|
impl<'a> CompressorPass<'a> for PeepholeFoldConstants {
|
||||||
fn changed(&self) -> bool {
|
|
||||||
self.changed
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build(&mut self, program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>) {
|
fn build(&mut self, program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>) {
|
||||||
self.changed = false;
|
self.changed = false;
|
||||||
traverse_mut_with_ctx(self, program, ctx);
|
traverse_mut_with_ctx(self, program, ctx);
|
||||||
|
|
|
||||||
|
|
@ -13,14 +13,10 @@ use crate::CompressorPass;
|
||||||
///
|
///
|
||||||
/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/PeepholeMinimizeConditions.java>
|
/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/PeepholeMinimizeConditions.java>
|
||||||
pub struct PeepholeMinimizeConditions {
|
pub struct PeepholeMinimizeConditions {
|
||||||
changed: bool,
|
pub(crate) changed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CompressorPass<'a> for PeepholeMinimizeConditions {
|
impl<'a> CompressorPass<'a> for PeepholeMinimizeConditions {
|
||||||
fn changed(&self) -> bool {
|
|
||||||
self.changed
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build(&mut self, program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>) {
|
fn build(&mut self, program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>) {
|
||||||
self.changed = false;
|
self.changed = false;
|
||||||
traverse_mut_with_ctx(self, program, ctx);
|
traverse_mut_with_ctx(self, program, ctx);
|
||||||
|
|
|
||||||
|
|
@ -14,14 +14,10 @@ use crate::{keep_var::KeepVar, CompressorPass};
|
||||||
/// See `KeepVar` at the end of this file for `var` hoisting logic.
|
/// See `KeepVar` at the end of this file for `var` hoisting logic.
|
||||||
/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/PeepholeRemoveDeadCode.java>
|
/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/PeepholeRemoveDeadCode.java>
|
||||||
pub struct PeepholeRemoveDeadCode {
|
pub struct PeepholeRemoveDeadCode {
|
||||||
changed: bool,
|
pub(crate) changed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CompressorPass<'a> for PeepholeRemoveDeadCode {
|
impl<'a> CompressorPass<'a> for PeepholeRemoveDeadCode {
|
||||||
fn changed(&self) -> bool {
|
|
||||||
self.changed
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build(&mut self, program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>) {
|
fn build(&mut self, program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>) {
|
||||||
self.changed = false;
|
self.changed = false;
|
||||||
traverse_mut_with_ctx(self, program, ctx);
|
traverse_mut_with_ctx(self, program, ctx);
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,10 @@ use crate::{node_util::Ctx, CompressorPass};
|
||||||
/// Minimize With Known Methods
|
/// Minimize With Known Methods
|
||||||
/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/PeepholeReplaceKnownMethods.java>
|
/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/PeepholeReplaceKnownMethods.java>
|
||||||
pub struct PeepholeReplaceKnownMethods {
|
pub struct PeepholeReplaceKnownMethods {
|
||||||
changed: bool,
|
pub(crate) changed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CompressorPass<'a> for PeepholeReplaceKnownMethods {
|
impl<'a> CompressorPass<'a> for PeepholeReplaceKnownMethods {
|
||||||
fn changed(&self) -> bool {
|
|
||||||
self.changed
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build(&mut self, program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>) {
|
fn build(&mut self, program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>) {
|
||||||
self.changed = false;
|
self.changed = false;
|
||||||
traverse_mut_with_ctx(self, program, ctx);
|
traverse_mut_with_ctx(self, program, ctx);
|
||||||
|
|
|
||||||
|
|
@ -24,14 +24,10 @@ pub struct PeepholeSubstituteAlternateSyntax {
|
||||||
// states
|
// states
|
||||||
in_define_export: bool,
|
in_define_export: bool,
|
||||||
|
|
||||||
changed: bool,
|
pub(crate) changed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CompressorPass<'a> for PeepholeSubstituteAlternateSyntax {
|
impl<'a> CompressorPass<'a> for PeepholeSubstituteAlternateSyntax {
|
||||||
fn changed(&self) -> bool {
|
|
||||||
self.changed
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build(&mut self, program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>) {
|
fn build(&mut self, program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>) {
|
||||||
self.changed = false;
|
self.changed = false;
|
||||||
traverse_mut_with_ctx(self, program, ctx);
|
traverse_mut_with_ctx(self, program, ctx);
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,6 @@ pub struct RemoveSyntax {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CompressorPass<'a> for RemoveSyntax {
|
impl<'a> CompressorPass<'a> for RemoveSyntax {
|
||||||
fn changed(&self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build(&mut self, program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>) {
|
fn build(&mut self, program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>) {
|
||||||
traverse_mut_with_ctx(self, program, ctx);
|
traverse_mut_with_ctx(self, program, ctx);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,14 +12,10 @@ use crate::CompressorPass;
|
||||||
///
|
///
|
||||||
/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/StatementFusion.java>
|
/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/StatementFusion.java>
|
||||||
pub struct StatementFusion {
|
pub struct StatementFusion {
|
||||||
changed: bool,
|
pub(crate) changed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CompressorPass<'a> for StatementFusion {
|
impl<'a> CompressorPass<'a> for StatementFusion {
|
||||||
fn changed(&self) -> bool {
|
|
||||||
self.changed
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build(&mut self, program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>) {
|
fn build(&mut self, program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>) {
|
||||||
self.changed = false;
|
self.changed = false;
|
||||||
traverse_mut_with_ctx(self, program, ctx);
|
traverse_mut_with_ctx(self, program, ctx);
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ use oxc_traverse::ReusableTraverseCtx;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast_passes::{
|
ast_passes::{
|
||||||
EarlyPass, LatePass, PeepholeFoldConstants, PeepholeMinimizeConditions,
|
CollapsePass, LatePeepholeOptimizations, PeepholeFoldConstants, PeepholeMinimizeConditions,
|
||||||
PeepholeRemoveDeadCode, RemoveSyntax,
|
PeepholeOptimizations, PeepholeRemoveDeadCode, RemoveSyntax,
|
||||||
},
|
},
|
||||||
CompressOptions, CompressorPass,
|
CompressOptions, CompressorPass,
|
||||||
};
|
};
|
||||||
|
|
@ -41,25 +41,10 @@ impl<'a> Compressor<'a> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut i = 0;
|
PeepholeOptimizations::new().build(program, &mut ctx);
|
||||||
loop {
|
CollapsePass::new().build(program, &mut ctx);
|
||||||
let mut changed = false;
|
LatePeepholeOptimizations::new().run_in_loop(program, &mut ctx);
|
||||||
let mut pass = EarlyPass::new();
|
PeepholeOptimizations::new().build(program, &mut ctx);
|
||||||
pass.build(program, &mut ctx);
|
|
||||||
if pass.changed() {
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
if !changed {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if i > 50 {
|
|
||||||
debug_assert!(false, "Ran in a infinite loop.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
LatePass::new().build(program, &mut ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dead_code_elimination(program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>) {
|
fn dead_code_elimination(program: &mut Program<'a>, ctx: &mut ReusableTraverseCtx<'a>) {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ Original | Minified | esbuild | Gzip | esbuild
|
||||||
|
|
||||||
173.90 kB | 61.16 kB | 59.82 kB | 19.62 kB | 19.33 kB | moment.js
|
173.90 kB | 61.16 kB | 59.82 kB | 19.62 kB | 19.33 kB | moment.js
|
||||||
|
|
||||||
287.63 kB | 91.70 kB | 90.07 kB | 32.35 kB | 31.95 kB | jquery.js
|
287.63 kB | 91.70 kB | 90.07 kB | 32.34 kB | 31.95 kB | jquery.js
|
||||||
|
|
||||||
342.15 kB | 120.23 kB | 118.14 kB | 44.72 kB | 44.37 kB | vue.js
|
342.15 kB | 120.23 kB | 118.14 kB | 44.72 kB | 44.37 kB | vue.js
|
||||||
|
|
||||||
|
|
@ -12,15 +12,15 @@ Original | Minified | esbuild | Gzip | esbuild
|
||||||
|
|
||||||
555.77 kB | 275.23 kB | 270.13 kB | 91.33 kB | 90.80 kB | d3.js
|
555.77 kB | 275.23 kB | 270.13 kB | 91.33 kB | 90.80 kB | d3.js
|
||||||
|
|
||||||
1.01 MB | 464.89 kB | 458.89 kB | 127.05 kB | 126.71 kB | bundle.min.js
|
1.01 MB | 464.89 kB | 458.89 kB | 127.04 kB | 126.71 kB | bundle.min.js
|
||||||
|
|
||||||
1.25 MB | 660.45 kB | 646.76 kB | 164.57 kB | 163.73 kB | three.js
|
1.25 MB | 660.45 kB | 646.76 kB | 164.46 kB | 163.73 kB | three.js
|
||||||
|
|
||||||
2.14 MB | 739.98 kB | 724.14 kB | 181.63 kB | 181.07 kB | victory.js
|
2.14 MB | 739.98 kB | 724.14 kB | 181.63 kB | 181.07 kB | victory.js
|
||||||
|
|
||||||
3.20 MB | 1.02 MB | 1.01 MB | 333.05 kB | 331.56 kB | echarts.js
|
3.20 MB | 1.02 MB | 1.01 MB | 333.04 kB | 331.56 kB | echarts.js
|
||||||
|
|
||||||
6.69 MB | 2.39 MB | 2.31 MB | 496.76 kB | 488.28 kB | antd.js
|
6.69 MB | 2.39 MB | 2.31 MB | 496.74 kB | 488.28 kB | antd.js
|
||||||
|
|
||||||
10.95 MB | 3.55 MB | 3.49 MB | 913.60 kB | 915.50 kB | typescript.js
|
10.95 MB | 3.55 MB | 3.49 MB | 913.59 kB | 915.50 kB | typescript.js
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue