mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
feat(minifier): add skeleton for RemoveDeadCode ast pass (#3802)
This commit is contained in:
parent
8027b1e894
commit
f3c3970131
6 changed files with 82 additions and 4 deletions
|
|
@ -1,3 +1,7 @@
|
||||||
|
#![allow(clippy::wildcard_imports)]
|
||||||
|
|
||||||
|
mod remove_dead_code;
|
||||||
mod remove_parens;
|
mod remove_parens;
|
||||||
|
|
||||||
|
pub use remove_dead_code::RemoveDeadCode;
|
||||||
pub use remove_parens::RemoveParens;
|
pub use remove_parens::RemoveParens;
|
||||||
|
|
|
||||||
45
crates/oxc_minifier/src/ast_passes/remove_dead_code.rs
Normal file
45
crates/oxc_minifier/src/ast_passes/remove_dead_code.rs
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
use oxc_allocator::Allocator;
|
||||||
|
use oxc_ast::{ast::*, visit::walk_mut, AstBuilder, VisitMut};
|
||||||
|
use oxc_span::SPAN;
|
||||||
|
|
||||||
|
/// Remove Dead Code from the AST.
|
||||||
|
///
|
||||||
|
/// Terser option: `dead_code: true`.
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct RemoveDeadCode<'a> {
|
||||||
|
ast: AstBuilder<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> RemoveDeadCode<'a> {
|
||||||
|
pub fn new(allocator: &'a Allocator) -> Self {
|
||||||
|
Self { ast: AstBuilder::new(allocator) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build(&mut self, program: &mut Program<'a>) {
|
||||||
|
self.visit_program(program);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_if(&mut self, stmt: &mut Statement<'a>) {
|
||||||
|
let Statement::IfStatement(if_stmt) = stmt else { return };
|
||||||
|
match if_stmt.test.get_boolean_value() {
|
||||||
|
Some(true) => {
|
||||||
|
*stmt = self.ast.move_statement(&mut if_stmt.consequent);
|
||||||
|
}
|
||||||
|
Some(false) => {
|
||||||
|
*stmt = if let Some(alternate) = &mut if_stmt.alternate {
|
||||||
|
self.ast.move_statement(alternate)
|
||||||
|
} else {
|
||||||
|
self.ast.empty_statement(SPAN)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> VisitMut<'a> for RemoveDeadCode<'a> {
|
||||||
|
fn visit_statement(&mut self, stmt: &mut Statement<'a>) {
|
||||||
|
self.remove_if(stmt);
|
||||||
|
walk_mut::walk_statement_mut(self, stmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
use oxc_allocator::{Allocator, Vec};
|
use oxc_allocator::{Allocator, Vec};
|
||||||
use oxc_ast::visit::walk_mut::{walk_expression_mut, walk_statements_mut};
|
use oxc_ast::{
|
||||||
#[allow(clippy::wildcard_imports)]
|
ast::*,
|
||||||
use oxc_ast::{ast::*, AstBuilder, VisitMut};
|
visit::walk_mut::{walk_expression_mut, walk_statements_mut},
|
||||||
|
AstBuilder, VisitMut,
|
||||||
|
};
|
||||||
|
|
||||||
/// Remove Parenthesized Expression from the AST.
|
/// Remove Parenthesized Expression from the AST.
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use oxc_allocator::Allocator;
|
||||||
use oxc_ast::ast::Program;
|
use oxc_ast::ast::Program;
|
||||||
|
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
ast_passes::RemoveParens,
|
ast_passes::{RemoveDeadCode, RemoveParens},
|
||||||
compressor::{CompressOptions, Compressor},
|
compressor::{CompressOptions, Compressor},
|
||||||
mangler::ManglerBuilder,
|
mangler::ManglerBuilder,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
mod code_removal;
|
mod code_removal;
|
||||||
mod folding;
|
mod folding;
|
||||||
mod precedence;
|
mod precedence;
|
||||||
|
mod remove_dead_code;
|
||||||
|
|
|
||||||
26
crates/oxc_minifier/tests/oxc/remove_dead_code.rs
Normal file
26
crates/oxc_minifier/tests/oxc/remove_dead_code.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
use oxc_allocator::Allocator;
|
||||||
|
use oxc_codegen::WhitespaceRemover;
|
||||||
|
use oxc_minifier::RemoveDeadCode;
|
||||||
|
use oxc_parser::Parser;
|
||||||
|
use oxc_span::SourceType;
|
||||||
|
|
||||||
|
fn minify(source_text: &str) -> String {
|
||||||
|
let source_type = SourceType::default();
|
||||||
|
let allocator = Allocator::default();
|
||||||
|
let ret = Parser::new(&allocator, source_text, source_type).parse();
|
||||||
|
let program = allocator.alloc(ret.program);
|
||||||
|
RemoveDeadCode::new(&allocator).build(program);
|
||||||
|
WhitespaceRemover::new().build(program).source_text
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn test(source_text: &str, expected: &str) {
|
||||||
|
let minified = minify(source_text);
|
||||||
|
assert_eq!(minified, expected, "for source {source_text}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn remove_dead_code() {
|
||||||
|
test("if (true) { foo }", "{foo}");
|
||||||
|
test("if (true) { foo } else { bar }", "{foo}");
|
||||||
|
test("if (false) { foo } else { bar }", "{bar}");
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue