feat(minifier): minimize foo(...[]) -> foo() (#8726)

This commit is contained in:
Boshen 2025-01-26 10:30:33 +00:00
parent ad87fc7a53
commit cbe0e8239d
2 changed files with 25 additions and 0 deletions

View file

@ -306,6 +306,14 @@ impl<'a> Traverse<'a> for LatePeepholeOptimizations {
fn exit_catch_clause(&mut self, catch: &mut CatchClause<'a>, ctx: &mut TraverseCtx<'a>) {
self.substitute_catch_clause(catch, Ctx(ctx));
}
fn exit_call_expression(&mut self, e: &mut CallExpression<'a>, _ctx: &mut TraverseCtx<'a>) {
Self::remove_empty_spread_arguments(&mut e.arguments);
}
fn exit_new_expression(&mut self, e: &mut NewExpression<'a>, _ctx: &mut TraverseCtx<'a>) {
Self::remove_empty_spread_arguments(&mut e.arguments);
}
}
pub struct DeadCodeElimination {

View file

@ -620,6 +620,17 @@ impl<'a> LatePeepholeOptimizations {
pub fn remove_dead_code_exit_class_body(body: &mut ClassBody<'a>, _ctx: Ctx<'a, '_>) {
body.body.retain(|e| !matches!(e, ClassElement::StaticBlock(s) if s.body.is_empty()));
}
pub fn remove_empty_spread_arguments(args: &mut Vec<'a, Argument<'a>>) {
if args.len() != 1 {
return;
}
let Argument::SpreadElement(e) = &args[0] else { return };
let Expression::ArrayExpression(e) = &e.argument else { return };
if e.elements.is_empty() {
args.drain(..);
}
}
}
/// <https://github.com/google/closure-compiler/blob/v20240609/test/com/google/javascript/jscomp/PeepholeRemoveDeadCodeTest.java>
@ -898,4 +909,10 @@ mod test {
test_same("throw foo; export let bar");
test_same("throw foo; export default bar");
}
#[test]
fn remove_empty_spread_arguments() {
test("foo(...[])", "foo()");
test("new Foo(...[])", "new Foo()");
}
}