feat(minifier): reenable minifier tests (#969)

This commit is contained in:
Boshen 2023-10-09 11:25:29 +08:00 committed by GitHub
parent 0fcad27515
commit 14e1dacd0a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 82 additions and 29 deletions

View file

@ -2,6 +2,7 @@
mod ast_util;
mod fold;
mod prepass;
mod util;
use oxc_allocator::{Allocator, Vec};
@ -14,6 +15,8 @@ use oxc_syntax::{
NumberBase,
};
use self::prepass::Prepass;
#[allow(clippy::struct_excessive_bools)]
#[derive(Debug, Clone, Copy)]
pub struct CompressOptions {
@ -70,16 +73,19 @@ impl Default for CompressOptions {
pub struct Compressor<'a> {
ast: AstBuilder<'a>,
options: CompressOptions,
prepass: Prepass<'a>,
}
const SPAN: Span = Span::new(0, 0);
impl<'a> Compressor<'a> {
pub fn new(allocator: &'a Allocator, options: CompressOptions) -> Self {
Self { ast: AstBuilder::new(allocator), options }
Self { ast: AstBuilder::new(allocator), options, prepass: Prepass::new(allocator) }
}
pub fn build<'b>(mut self, program: &'b mut Program<'a>) {
self.prepass.visit_program(program);
self.visit_program(program);
}
@ -208,16 +214,15 @@ impl<'a> Compressor<'a> {
/* Expressions */
/// Transforms `undefined` => `void 0`
fn compress_undefined<'b>(&mut self, _expr: &'b mut Expression<'a>) -> bool {
// let Expression::Identifier(ident) = expr else { return false };
// if let Some(reference_id) = ident.reference_id.clone().into_inner() {
// if ident.name == "undefined"
// && self.semantic.symbols().is_global_reference(reference_id)
// {
// *expr = self.create_void_0();
// return true;
// }
// }
fn compress_undefined<'b>(&mut self, expr: &'b mut Expression<'a>) -> bool {
let Expression::Identifier(ident) = expr else { return false };
if ident.name == "undefined" {
// if let Some(reference_id) = ident.reference_id.clone().into_inner() {
// && self.semantic.symbols().is_global_reference(reference_id)
*expr = self.create_void_0();
return true;
// }
}
false
}
@ -225,13 +230,13 @@ impl<'a> Compressor<'a> {
#[allow(unused)]
fn compress_infinity<'b>(&mut self, expr: &'b mut Expression<'a>) -> bool {
let Expression::Identifier(ident) = expr else { return false };
// if let Some(reference_id) = ident.reference_id.clone().into_inner() {
// if ident.name == "Infinity" && self.semantic.symbols().is_global_reference(reference_id)
// {
// *expr = self.create_one_div_zero();
// return true;
// }
// }
if ident.name == "Infinity" {
// if let Some(reference_id) = ident.reference_id.clone().into_inner() {
//&& self.semantic.symbols().is_global_reference(reference_id)
*expr = self.create_one_div_zero();
return true;
// }
}
false
}
@ -319,7 +324,18 @@ impl<'a> Compressor<'a> {
impl<'a, 'b> VisitMut<'a, 'b> for Compressor<'a> {
fn visit_statements(&mut self, stmts: &'b mut Vec<'a, Statement<'a>>) {
stmts.retain(|stmt| !(self.drop_debugger(stmt) || self.drop_console(stmt)));
stmts.retain(|stmt| {
if matches!(stmt, Statement::EmptyStatement(_)) {
return false;
}
if self.drop_debugger(stmt) {
return false;
}
if self.drop_console(stmt) {
return false;
}
true
});
self.join_vars(stmts);

View file

@ -0,0 +1,28 @@
use oxc_allocator::Allocator;
#[allow(clippy::wildcard_imports)]
use oxc_ast::{ast::*, AstBuilder, VisitMut};
pub struct Prepass<'a> {
ast: AstBuilder<'a>,
}
impl<'a> Prepass<'a> {
pub fn new(allocator: &'a Allocator) -> Self {
Self { ast: AstBuilder::new(allocator) }
}
fn strip_parenthesized_expression<'b>(&self, expr: &'b mut Expression<'a>) {
if let Expression::ParenthesizedExpression(paren_expr) = expr {
*expr = self.ast.move_expression(&mut paren_expr.expression);
self.strip_parenthesized_expression(expr);
}
}
}
impl<'a, 'b> VisitMut<'a, 'b> for Prepass<'a> {
fn visit_expression(&mut self, expr: &'b mut Expression<'a>) {
self.strip_parenthesized_expression(expr);
self.visit_expression_match(expr);
}
}

View file

@ -76,8 +76,9 @@ impl<'a> Gen for Statement<'a> {
Self::BreakStatement(stmt) => stmt.gen(p, ctx),
Self::ContinueStatement(stmt) => stmt.gen(p, ctx),
Self::DebuggerStatement(stmt) => stmt.gen(p, ctx),
Self::Declaration(decl) => decl.gen(p, ctx),
Self::DoWhileStatement(stmt) => stmt.gen(p, ctx),
Self::EmptyStatement(decl) => {}
Self::EmptyStatement(stmt) => stmt.gen(p, ctx),
Self::ExpressionStatement(stmt) => stmt.gen(p, ctx),
Self::ForInStatement(stmt) => stmt.gen(p, ctx),
Self::ForOfStatement(stmt) => stmt.gen(p, ctx),
@ -91,7 +92,6 @@ impl<'a> Gen for Statement<'a> {
Self::TryStatement(stmt) => stmt.gen(p, ctx),
Self::WhileStatement(stmt) => stmt.gen(p, ctx),
Self::WithStatement(stmt) => stmt.gen(p, ctx),
Self::Declaration(decl) => decl.gen(p, ctx),
}
}
}
@ -295,6 +295,12 @@ impl<'a> Gen for DoWhileStatement<'a> {
}
}
impl Gen for EmptyStatement {
fn gen(&self, p: &mut Printer, ctx: Context) {
p.print(b';');
}
}
impl Gen for ContinueStatement {
fn gen(&self, p: &mut Printer, ctx: Context) {
p.print_str(b"continue");
@ -768,6 +774,9 @@ impl<'a> GenExpr for Expression<'a> {
Self::ClassExpression(expr) => expr.gen(p, ctx),
Self::JSXElement(el) => el.gen(p, ctx),
Self::JSXFragment(fragment) => fragment.gen(p, ctx),
Self::ParenthesizedExpression(_) => {
panic!("The compressor mut strip this ParenthesizedExpression.")
}
_ => {}
}
}

View file

@ -14,10 +14,10 @@ pub(crate) fn test(source_text: &str, expected: &str) {
test_with_options(source_text, expected, options);
}
pub(crate) fn test_with_options(source_text: &str, _expected: &str, options: MinifierOptions) {
pub(crate) fn test_with_options(source_text: &str, expected: &str, options: MinifierOptions) {
let source_type = SourceType::default();
let _minified = Minifier::new(source_text, source_type, options).build();
// assert_eq!(expected, minified, "for source {source_text}");
let minified = Minifier::new(source_text, source_type, options).build();
assert_eq!(expected, minified, "for source {source_text}");
}
pub(crate) fn test_same(source_text: &str) {
@ -28,17 +28,17 @@ pub(crate) fn test_reparse(source_text: &str) {
let source_type = SourceType::default();
let options = MinifierOptions { mangle: false, ..MinifierOptions::default() };
let minified = Minifier::new(source_text, source_type, options).build();
let _minified2 = Minifier::new(&minified, source_type, options).build();
// assert_eq!(minified, minified2, "for source {source_text}");
let minified2 = Minifier::new(&minified, source_type, options).build();
assert_eq!(minified, minified2, "for source {source_text}");
}
pub(crate) fn test_without_compress_booleans(source_text: &str, _expected: &str) {
pub(crate) fn test_without_compress_booleans(source_text: &str, expected: &str) {
let source_type = SourceType::default();
let compress_options = CompressOptions { booleans: false, ..CompressOptions::default() };
let options =
MinifierOptions { mangle: false, compress: compress_options, print: PrinterOptions };
let _minified = Minifier::new(source_text, source_type, options).build();
// assert_eq!(expected, minified, "for source {source_text}");
let minified = Minifier::new(source_text, source_type, options).build();
assert_eq!(expected, minified, "for source {source_text}");
}
pub(crate) fn test_snapshot<S>(name: &str, sources: S)