Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions crates/oxc_minifier/src/peephole/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,14 @@ impl<'a> Traverse<'a> for PeepholeOptimizations {
self.substitute_call_expression(expr, ctx);
}

fn exit_new_expression(&mut self, expr: &mut NewExpression<'a>, ctx: &mut TraverseCtx<'a>) {
if !self.is_prev_function_changed() {
return;
}
let ctx = Ctx(ctx);
self.substitute_new_expression(expr, ctx);
}

fn exit_object_property(&mut self, prop: &mut ObjectProperty<'a>, ctx: &mut TraverseCtx<'a>) {
if !self.is_prev_function_changed() {
return;
Expand Down
79 changes: 41 additions & 38 deletions crates/oxc_minifier/src/peephole/substitute_alternate_syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,11 @@ impl<'a> PeepholeOptimizations {
}

pub fn substitute_call_expression(&mut self, expr: &mut CallExpression<'a>, ctx: Ctx<'a, '_>) {
self.try_compress_call_expression_arguments(expr, ctx);
self.try_flatten_arguments(&mut expr.arguments, ctx);
}

pub fn substitute_new_expression(&mut self, expr: &mut NewExpression<'a>, ctx: Ctx<'a, '_>) {
self.try_flatten_arguments(&mut expr.arguments, ctx);
}

pub fn substitute_exit_expression(&mut self, expr: &mut Expression<'a>, ctx: Ctx<'a, '_>) {
Expand Down Expand Up @@ -873,13 +877,10 @@ impl<'a> PeepholeOptimizations {
}

// `foo(...[1,2,3])` -> `foo(1,2,3)`
fn try_compress_call_expression_arguments(
&mut self,
node: &mut CallExpression<'a>,
ctx: Ctx<'a, '_>,
) {
// `new Foo(...[1,2,3])` -> `new Foo(1,2,3)`
fn try_flatten_arguments(&mut self, args: &mut Vec<'a, Argument<'a>>, ctx: Ctx<'a, '_>) {
let (new_size, should_fold) =
node.arguments.iter().fold((0, false), |(mut new_size, mut should_fold), arg| {
args.iter().fold((0, false), |(mut new_size, mut should_fold), arg| {
new_size += if let Argument::SpreadElement(spread_el) = arg {
if let Expression::ArrayExpression(array_expr) = &spread_el.argument {
should_fold = true;
Expand All @@ -893,45 +894,44 @@ impl<'a> PeepholeOptimizations {

(new_size, should_fold)
});
if !should_fold {
return;
}

if should_fold {
let old_args =
std::mem::replace(&mut node.arguments, ctx.ast.vec_with_capacity(new_size));
let new_args = &mut node.arguments;

for arg in old_args {
if let Argument::SpreadElement(mut spread_el) = arg {
if let Expression::ArrayExpression(array_expr) = &mut spread_el.argument {
for el in &mut array_expr.elements {
match el {
ArrayExpressionElement::SpreadElement(spread_el) => {
new_args.push(ctx.ast.argument_spread_element(
spread_el.span,
ctx.ast.move_expression(&mut spread_el.argument),
));
}
ArrayExpressionElement::Elision(elision) => {
new_args.push(ctx.ast.void_0(elision.span).into());
}
match_expression!(ArrayExpressionElement) => {
new_args.push(
ctx.ast.move_expression(el.to_expression_mut()).into(),
);
}
let old_args = std::mem::replace(args, ctx.ast.vec_with_capacity(new_size));
let new_args = args;

for arg in old_args {
if let Argument::SpreadElement(mut spread_el) = arg {
if let Expression::ArrayExpression(array_expr) = &mut spread_el.argument {
for el in &mut array_expr.elements {
match el {
ArrayExpressionElement::SpreadElement(spread_el) => {
new_args.push(ctx.ast.argument_spread_element(
spread_el.span,
ctx.ast.move_expression(&mut spread_el.argument),
));
}
ArrayExpressionElement::Elision(elision) => {
new_args.push(ctx.ast.void_0(elision.span).into());
}
match_expression!(ArrayExpressionElement) => {
new_args
.push(ctx.ast.move_expression(el.to_expression_mut()).into());
}
}
} else {
new_args.push(ctx.ast.argument_spread_element(
spread_el.span,
ctx.ast.move_expression(&mut spread_el.argument),
));
}
} else {
new_args.push(arg);
new_args.push(ctx.ast.argument_spread_element(
spread_el.span,
ctx.ast.move_expression(&mut spread_el.argument),
));
}
} else {
new_args.push(arg);
}
self.mark_current_function_as_changed();
}
self.mark_current_function_as_changed();
}
}

Expand Down Expand Up @@ -1618,12 +1618,15 @@ mod test {
test_same("f(...a)");
test_same("f(...a, ...b)");
test_same("f(...a, b, ...c)");
test_same("new F(...a)");

test("f(...[])", "f()");
test("f(...[1])", "f(1)");
test("f(...[1, 2])", "f(1, 2)");
test("f(...[1,,,3])", "f(1, void 0, void 0, 3)");
test("f(a, ...[])", "f(a)");
test("new F(...[])", "new F()");
test("new F(...[1])", "new F(1)");
}

#[test]
Expand Down
Loading