Skip to content

Commit

Permalink
feat(minifier): implement StatementFusion
Browse files Browse the repository at this point in the history
  • Loading branch information
Boshen committed Sep 20, 2024
1 parent 6757c58 commit d51fcae
Showing 1 changed file with 59 additions and 5 deletions.
64 changes: 59 additions & 5 deletions crates/oxc_minifier/src/ast_passes/statement_fusion.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use oxc_traverse::Traverse;
use oxc_allocator::Vec;
use oxc_ast::ast::*;
use oxc_span::SPAN;
use oxc_traverse::{Traverse, TraverseCtx};

use crate::CompressorPass;

Expand All @@ -11,12 +14,65 @@ pub struct StatementFusion;

impl<'a> CompressorPass<'a> for StatementFusion {}

impl<'a> Traverse<'a> for StatementFusion {}
impl<'a> Traverse<'a> for StatementFusion {
fn enter_program(&mut self, program: &mut Program<'a>, ctx: &mut TraverseCtx<'a>) {
Self::fuse_statements(&mut program.body, ctx);
}

fn enter_function_body(&mut self, body: &mut FunctionBody<'a>, ctx: &mut TraverseCtx<'a>) {
Self::fuse_statements(&mut body.statements, ctx);
}
}

impl StatementFusion {
impl<'a> StatementFusion {
pub fn new() -> Self {
Self {}
}

fn fuse_statements(stmts: &mut Vec<'a, Statement<'a>>, ctx: &mut TraverseCtx<'a>) {
if stmts.len() < 1 {
return;
}

let mut expressions = ctx.ast.vec();

for stmt in stmts.iter_mut() {
match stmt {
// `a; b; c;` -> `a, b, c`
Statement::ExpressionStatement(expr_stmt) => {
expressions.push(ctx.ast.move_expression(&mut expr_stmt.expression));
// Replace with an empty statement to filter it out later.
*stmt = ctx.ast.statement_empty(SPAN);
}
// `a; b; if (c) {}` -> `if (a, b, c) {}`
Statement::IfStatement(if_stmt) => {
expressions.push(ctx.ast.move_expression(&mut if_stmt.test));
if_stmt.test =
ctx.ast.expression_sequence(SPAN, ctx.ast.move_vec(&mut expressions));
}
_ => {}
}
}

if !expressions.is_empty() {
*stmts.last_mut().unwrap() =
ctx.ast.statement_expression(SPAN, ctx.ast.expression_sequence(SPAN, expressions));
}

stmts.retain(|stmt| !matches!(stmt, Statement::EmptyStatement(_)))
}

fn is_fusable_control_statement() -> bool {
false
}

fn fuse_into_one_statement(
stmts: &Vec<'a, Statement<'a>>,
ctx: &mut TraverseCtx<'a>,
) -> Vec<'a, Statement<'a>> {
let v = ctx.ast.vec();
v
}
}

#[cfg(test)]
Expand Down Expand Up @@ -47,7 +103,6 @@ mod test {
}

#[test]
#[ignore]
fn nothing_to_do() {
fuse_same("");
fuse_same("a");
Expand All @@ -56,7 +111,6 @@ mod test {
}

#[test]
#[ignore]
fn fold_block_with_statements() {
fuse("a;b;c", "a,b,c");
fuse("a();b();c();", "a(),b(),c()");
Expand Down

0 comments on commit d51fcae

Please sign in to comment.