@@ -1125,11 +1125,12 @@ impl<'a> PeepholeOptimizations {
1125
1125
/// Evaluation here means `Evaluation` in the spec.
1126
1126
/// <https://tc39.es/ecma262/multipage/syntax-directed-operations.html#sec-evaluation>
1127
1127
///
1128
- /// Matches the following cases:
1128
+ /// Matches the following cases (`a` can be `this`) :
1129
1129
///
1130
1130
/// - `a`, `a`
1131
1131
/// - `a.b`, `a.b`
1132
1132
/// - `a["b"]`, `a["b"]`
1133
+ /// - `a[0]`, `a[0]`
1133
1134
fn has_no_side_effect_for_evaluation_same_target (
1134
1135
assignment_target : & AssignmentTarget ,
1135
1136
expr : & Expression ,
@@ -1144,18 +1145,29 @@ impl<'a> PeepholeOptimizations {
1144
1145
}
1145
1146
if let Some ( write_expr) = assignment_target. as_member_expression ( ) {
1146
1147
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
+ ) {
1148
1152
return false ;
1149
1153
}
1150
1154
}
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 ( ) {
1155
1156
// It should also return false when the reference might refer to a reference value created by a with statement
1156
1157
// 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) ;
1159
1171
}
1160
1172
}
1161
1173
false
@@ -2475,11 +2487,15 @@ mod test {
2475
2487
test ( "x || (x = () => 'a')" , "x ||= () => 'a'" ) ;
2476
2488
2477
2489
test_same ( "x || (y = 3)" ) ;
2490
+ test_same ( "var x; x.y || (x.z = 3)" ) ;
2491
+ test_same ( "function _() { this.x || (this.y = 3) }" ) ;
2478
2492
2479
2493
// GetValue(x) has no sideeffect when x is a resolved identifier
2480
2494
test ( "var x; x.y || (x.y = 3)" , "var x; x.y ||= 3" ) ;
2481
2495
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" ) ;
2482
2497
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 }" ) ;
2483
2499
test_same ( "x.y || (x.y = 3)" ) ;
2484
2500
// this can be compressed if `y` does not have side effect
2485
2501
test_same ( "var x; x[y] || (x[y] = 3)" ) ;
0 commit comments