Skip to content

Commit 3c1c92c

Browse files
committed
feat(minifier): support a[0] and this.a in has_no_side_effect_for_evaluation_same_target (#8748)
Add support for `a[0]` and `this.a` in `has_no_side_effect_for_evaluation_same_target` function.
1 parent a3b078a commit 3c1c92c

File tree

2 files changed

+30
-14
lines changed

2 files changed

+30
-14
lines changed

crates/oxc_minifier/src/peephole/minimize_conditions.rs

+24-8
Original file line numberDiff line numberDiff line change
@@ -1125,11 +1125,12 @@ impl<'a> PeepholeOptimizations {
11251125
/// Evaluation here means `Evaluation` in the spec.
11261126
/// <https://tc39.es/ecma262/multipage/syntax-directed-operations.html#sec-evaluation>
11271127
///
1128-
/// Matches the following cases:
1128+
/// Matches the following cases (`a` can be `this`):
11291129
///
11301130
/// - `a`, `a`
11311131
/// - `a.b`, `a.b`
11321132
/// - `a["b"]`, `a["b"]`
1133+
/// - `a[0]`, `a[0]`
11331134
fn has_no_side_effect_for_evaluation_same_target(
11341135
assignment_target: &AssignmentTarget,
11351136
expr: &Expression,
@@ -1144,18 +1145,29 @@ impl<'a> PeepholeOptimizations {
11441145
}
11451146
if let Some(write_expr) = assignment_target.as_member_expression() {
11461147
if let MemberExpression::ComputedMemberExpression(e) = write_expr {
1147-
if !matches!(e.expression, Expression::StringLiteral(_)) {
1148+
if !matches!(
1149+
e.expression,
1150+
Expression::StringLiteral(_) | Expression::NumericLiteral(_)
1151+
) {
11481152
return false;
11491153
}
11501154
}
1151-
let Expression::Identifier(write_expr_object_id) = &write_expr.object() else {
1152-
return false;
1153-
};
1154-
if let Some(read_expr) = expr.as_member_expression() {
1155+
let has_same_object = match &write_expr.object() {
11551156
// It should also return false when the reference might refer to a reference value created by a with statement
11561157
// when the minifier supports with statements
1157-
return !ctx.is_global_reference(write_expr_object_id)
1158-
&& write_expr.content_eq(read_expr);
1158+
Expression::Identifier(ident) => !ctx.is_global_reference(ident),
1159+
Expression::ThisExpression(_) => {
1160+
expr.as_member_expression().is_some_and(|read_expr| {
1161+
matches!(read_expr.object(), Expression::ThisExpression(_))
1162+
})
1163+
}
1164+
_ => false,
1165+
};
1166+
if !has_same_object {
1167+
return false;
1168+
}
1169+
if let Some(read_expr) = expr.as_member_expression() {
1170+
return write_expr.content_eq(read_expr);
11591171
}
11601172
}
11611173
false
@@ -2475,11 +2487,15 @@ mod test {
24752487
test("x || (x = () => 'a')", "x ||= () => 'a'");
24762488

24772489
test_same("x || (y = 3)");
2490+
test_same("var x; x.y || (x.z = 3)");
2491+
test_same("function _() { this.x || (this.y = 3) }");
24782492

24792493
// GetValue(x) has no sideeffect when x is a resolved identifier
24802494
test("var x; x.y || (x.y = 3)", "var x; x.y ||= 3");
24812495
test("var x; x['y'] || (x['y'] = 3)", "var x; x.y ||= 3");
2496+
test("var x; x[0] || (x[0] = 3)", "var x; x[0] ||= 3");
24822497
test("var x; x.#y || (x.#y = 3)", "var x; x.#y ||= 3");
2498+
test("function _() { this.x || (this.x = 3) }", "function _() { this.x ||= 3 }");
24832499
test_same("x.y || (x.y = 3)");
24842500
// this can be compressed if `y` does not have side effect
24852501
test_same("var x; x[y] || (x[y] = 3)");

tasks/minsize/minsize.snap

+6-6
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,21 @@ Original | minified | minified | gzip | gzip | Fixture
77

88
287.63 kB | 89.58 kB | 90.07 kB | 31.08 kB | 31.95 kB | jquery.js
99

10-
342.15 kB | 117.76 kB | 118.14 kB | 43.67 kB | 44.37 kB | vue.js
10+
342.15 kB | 117.72 kB | 118.14 kB | 43.66 kB | 44.37 kB | vue.js
1111

1212
544.10 kB | 71.50 kB | 72.48 kB | 25.92 kB | 26.20 kB | lodash.js
1313

1414
555.77 kB | 271.68 kB | 270.13 kB | 88.48 kB | 90.80 kB | d3.js
1515

1616
1.01 MB | 457.66 kB | 458.89 kB | 123.79 kB | 126.71 kB | bundle.min.js
1717

18-
1.25 MB | 650.70 kB | 646.76 kB | 161.49 kB | 163.73 kB | three.js
18+
1.25 MB | 650.64 kB | 646.76 kB | 161.49 kB | 163.73 kB | three.js
1919

20-
2.14 MB | 719.00 kB | 724.14 kB | 162.41 kB | 181.07 kB | victory.js
20+
2.14 MB | 718.99 kB | 724.14 kB | 162.41 kB | 181.07 kB | victory.js
2121

22-
3.20 MB | 1.01 MB | 1.01 MB | 325.38 kB | 331.56 kB | echarts.js
22+
3.20 MB | 1.01 MB | 1.01 MB | 325.29 kB | 331.56 kB | echarts.js
2323

24-
6.69 MB | 2.30 MB | 2.31 MB | 470.00 kB | 488.28 kB | antd.js
24+
6.69 MB | 2.30 MB | 2.31 MB | 469.99 kB | 488.28 kB | antd.js
2525

26-
10.95 MB | 3.37 MB | 3.49 MB | 866.64 kB | 915.50 kB | typescript.js
26+
10.95 MB | 3.37 MB | 3.49 MB | 866.60 kB | 915.50 kB | typescript.js
2727

0 commit comments

Comments
 (0)