Skip to content

Commit db7680b

Browse files
committed
feat(minifier): drop var r = [...arguments] if r is not used
1 parent ff1d148 commit db7680b

File tree

2 files changed

+88
-73
lines changed

2 files changed

+88
-73
lines changed

crates/oxc_minifier/src/peephole/substitute_alternate_syntax.rs

Lines changed: 86 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@ impl<'a> PeepholeOptimizations {
549549
assign_expr
550550
};
551551

552-
let (r_id_name, a_id_name, lhs_offset) = {
552+
let (r_id_name, a_id_name, offset) = {
553553
let AssignmentTarget::ComputedMemberExpression(lhs_member_expr) =
554554
&body_assign_expr.left
555555
else {
@@ -576,7 +576,7 @@ impl<'a> PeepholeOptimizations {
576576
(lhs_member_expr_obj.name, base_name, offset)
577577
};
578578

579-
let rhs_offset = {
579+
{
580580
let Expression::ComputedMemberExpression(rhs_member_expr) = &body_assign_expr.right
581581
else {
582582
return;
@@ -589,56 +589,13 @@ impl<'a> PeepholeOptimizations {
589589
{
590590
return;
591591
}
592-
match &rhs_member_expr.expression {
593-
Expression::Identifier(id) => {
594-
if id.name != a_id_name {
595-
return;
596-
}
597-
0.0
598-
}
599-
Expression::BinaryExpression(b) => {
600-
if b.operator != BinaryOperator::Addition {
601-
return;
602-
}
603-
let Some(((), offset)) = Self::commutative_pair(
604-
(&b.left, &b.right),
605-
|a| {
606-
if let Expression::Identifier(id) = a {
607-
if id.name != a_id_name {
608-
return None;
609-
}
610-
Some(())
611-
} else {
612-
None
613-
}
614-
},
615-
|b| {
616-
if let Expression::NumericLiteral(n) = b {
617-
if n.value.fract() == 0.0 && n.value >= 0.0 {
618-
Some(n.value)
619-
} else {
620-
None
621-
}
622-
} else {
623-
None
624-
}
625-
},
626-
) else {
627-
return;
628-
};
629-
offset
630-
}
631-
_ => return,
632-
}
633-
};
634-
635-
let offset = if lhs_offset == 0.0 {
636-
rhs_offset
637-
} else {
638-
if rhs_offset != 0.0 {
592+
let Expression::Identifier(rhs_member_expr_expr_id) = &rhs_member_expr.expression
593+
else {
594+
return;
595+
};
596+
if rhs_member_expr_expr_id.name != a_id_name {
639597
return;
640598
}
641-
lhs_offset
642599
};
643600

644601
// Parse update: `a++`
@@ -765,7 +722,11 @@ impl<'a> PeepholeOptimizations {
765722
if de_id.name != r_id_name {
766723
return;
767724
}
768-
de_r.id.take_in(ctx.ast)
725+
// `var r = [...arguments]` / `var r = [...arguments].slice(n)` is not needed
726+
// if r is not used by other places because `[...arguments]` does not have a sideeffect
727+
// `r` is used once in the for-loop (assignment for each index)
728+
(ctx.scoping().get_resolved_references(de_id.symbol_id()).count() > 1)
729+
.then(|| de_r.id.take_in(ctx.ast))
769730
};
770731

771732
// Build `var r = [...arguments]` (with optional `.slice(offset)`) as the only declarator and drop test/update/body.
@@ -803,8 +764,13 @@ impl<'a> PeepholeOptimizations {
803764
base_arr
804765
};
805766

806-
let new_decl = ctx.ast.variable_declarator(SPAN, var_init.kind, r_id_pat, Some(arr), false);
807-
var_init.declarations = ctx.ast.vec1(new_decl);
767+
var_init.declarations = if let Some(r_id_pat) = r_id_pat {
768+
let new_decl =
769+
ctx.ast.variable_declarator(SPAN, var_init.kind, r_id_pat, Some(arr), false);
770+
ctx.ast.vec1(new_decl)
771+
} else {
772+
ctx.ast.vec()
773+
};
808774
for_stmt.test =
809775
Some(ctx.ast.expression_numeric_literal(for_stmt.span, 0.0, None, NumberBase::Decimal));
810776
for_stmt.update = None;
@@ -2236,40 +2202,89 @@ mod test {
22362202
#[test]
22372203
fn test_rewrite_arguments_copy_loop() {
22382204
test(
2239-
"for (var e = arguments.length, r = Array(e), a = 0; a < e; a++) r[a] = arguments[a];",
2240-
"var r = [...arguments]",
2205+
"for (var e = arguments.length, r = Array(e), a = 0; a < e; a++) r[a] = arguments[a]; console.log(r)",
2206+
"var r = [...arguments]; console.log(r)",
2207+
);
2208+
test(
2209+
"for (var e = arguments.length, r = Array(e), a = 0; a < e; a++) { r[a] = arguments[a]; } console.log(r)",
2210+
"var r = [...arguments]; console.log(r)",
2211+
);
2212+
test(
2213+
"for (var e = arguments.length, r = Array(e), a = 0; a < e; a++) { r[a] = arguments[a] } console.log(r)",
2214+
"var r = [...arguments]; console.log(r)",
2215+
);
2216+
test(
2217+
"for (var e = arguments.length, r = new Array(e), a = 0; a < e; a++) r[a] = arguments[a]; console.log(r)",
2218+
"var r = [...arguments]; console.log(r)",
2219+
);
2220+
test(
2221+
"for (var e = arguments.length, r = Array(e > 1 ? e - 1 : 0), a = 1; a < e; a++) r[a - 1] = arguments[a]; console.log(r)",
2222+
"var r = [...arguments].slice(1); console.log(r)",
2223+
);
2224+
test(
2225+
"for (var e = arguments.length, r = Array(e > 2 ? e - 2 : 0), a = 2; a < e; a++) r[a - 2] = arguments[a]; console.log(r)",
2226+
"var r = [...arguments].slice(2); console.log(r)",
22412227
);
22422228
test(
2243-
"for (var e = arguments.length, r = Array(e), a = 0; a < e; a++) { r[a] = arguments[a] }",
2244-
"var r = [...arguments]",
2229+
"for (var e = arguments.length, r = [], a = 0; a < e; a++) r[a] = arguments[a]; console.log(r)",
2230+
"var r = [...arguments]; console.log(r)",
22452231
);
22462232
test(
2247-
"for (var e = arguments.length, r = new Array(e), a = 0; a < e; a++) r[a] = arguments[a];",
2248-
"var r = [...arguments]",
2233+
"for (var r = [], a = 0; a < arguments.length; a++) r[a] = arguments[a]; console.log(r)",
2234+
"var r = [...arguments]; console.log(r)",
22492235
);
22502236
test(
2251-
"for (var e = arguments.length, r = Array(e > 1 ? e - 1 : 0), a = 1; a < e; a++) r[a - 1] = arguments[a];",
2252-
"var r = [...arguments].slice(1)",
2237+
"for (var r = [], a = 1; a < arguments.length; a++) r[a - 1] = arguments[a]; console.log(r)",
2238+
"var r = [...arguments].slice(1); console.log(r)",
22532239
);
22542240
test(
2255-
"for (var e = arguments.length, r = Array(e > 2 ? e - 2 : 0), a = 2; a < e; a++) r[a - 2] = arguments[a];",
2256-
"var r = [...arguments].slice(2)",
2241+
"for (var r = [], a = 2; a < arguments.length; a++) r[a - 2] = arguments[a]; console.log(r)",
2242+
"var r = [...arguments].slice(2); console.log(r)",
22572243
);
22582244
test(
2259-
"for (var e = arguments.length, r = [], a = 0; a < e; a++) r[a] = arguments[a];",
2260-
"var r = [...arguments]",
2245+
"for (var e = arguments.length, r = Array(e), a = 0; a < e; a++) r[a] = arguments[a];",
2246+
"",
22612247
);
22622248
test(
2263-
"for (var r = [], a = 0; a < arguments.length; a++) r[a] = arguments[a];",
2264-
"var r = [...arguments]",
2249+
"for (var e = arguments.length, r = Array(e > 1 ? e - 1 : 0), a = 1; a < e; a++) r[a - 1] = arguments[a]",
2250+
"",
2251+
);
2252+
test_same(
2253+
"for (var e = arguments.length, r = Array(e), a = 0; a < e; a++) console.log(r[a]);",
22652254
);
22662255
test(
2267-
"for (var r = [], a = 1; a < arguments.length; a++) r[a - 1] = arguments[a];",
2268-
"var r = [...arguments].slice(1)",
2256+
"for (var e = arguments.length, r = Array(e), a = 0; a < e; a++) { r[a] = arguments[a]; console.log(r); }",
2257+
"for (var e = arguments.length, r = Array(e), a = 0; a < e; a++) (r[a] = arguments[a], console.log(r))",
2258+
);
2259+
test_same(
2260+
"for (var e = arguments.length, r = Array(e), a = 0; a < e; a++) r[a] += arguments[a];",
2261+
);
2262+
test_same(
2263+
"for (var e = arguments.length, r = Array(e), a = 0; a < e; a++) r[a + 1] = arguments[a];",
2264+
);
2265+
test_same(
2266+
"for (var e = arguments.length, r = Array(e), a = 0; a < e; a++) r[a - 0.5] = arguments[a];",
22692267
);
22702268
test(
2271-
"for (var r = [], a = 2; a < arguments.length; a++) r[a - 2] = arguments[a];",
2272-
"var r = [...arguments].slice(2)",
2269+
"var arguments; for (var e = arguments.length, r = Array(e), a = 0; a < e; a++) r[a] = arguments[a];",
2270+
"for (var arguments, e = arguments.length, r = Array(e), a = 0; a < e; a++) r[a] = arguments[a];",
2271+
);
2272+
test_same("for (var e = arguments.length, r = Array(e), a = 0; a < e; a++) r[a] = foo[a];");
2273+
test_same(
2274+
"for (var e = arguments.length, r = Array(e), a = 0; a < e; e--) r[a] = arguments[a];",
2275+
);
2276+
test_same(
2277+
"for (var e = arguments.length, r = Array(e), a = 0; a < e; r++) r[a] = arguments[a];",
2278+
);
2279+
test_same(
2280+
"for (var e = arguments.length, r = Array(e), a = 0; a < r; r++) r[a] = arguments[a];",
2281+
);
2282+
test(
2283+
"var arguments; for (var r = [], a = 0; a < arguments.length; a++) r[a] = arguments[a];",
2284+
"for (var arguments, r = [], a = 0; a < arguments.length; a++) r[a] = arguments[a];",
2285+
);
2286+
test_same(
2287+
"for (var e = arguments.length, r = Array(e > 1 ? e - 2 : 0), a = 2; a < e; a++) r[a - 2] = arguments[a];",
22732288
);
22742289
}
22752290
}

tasks/minsize/minsize.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ Original | minified | minified | gzip | gzip | Iterations | Fi
1919

2020
2.14 MB | 715.37 kB | 724.14 kB | 161.66 kB | 181.07 kB | 2 | victory.js
2121

22-
3.20 MB | 1.01 MB | 1.01 MB | 323.99 kB | 331.56 kB | 3 | echarts.js
22+
3.20 MB | 1.01 MB | 1.01 MB | 323.98 kB | 331.56 kB | 2 | echarts.js
2323

2424
6.69 MB | 2.23 MB | 2.31 MB | 461.69 kB | 488.28 kB | 3 | antd.js
2525

26-
10.95 MB | 3.35 MB | 3.49 MB | 860.60 kB | 915.50 kB | 3 | typescript.js
26+
10.95 MB | 3.35 MB | 3.49 MB | 860.59 kB | 915.50 kB | 2 | typescript.js
2727

0 commit comments

Comments
 (0)