diff --git a/lib/compress.js b/lib/compress.js index 95cccb565a..673426bfd0 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -814,26 +814,39 @@ merge(Compressor.prototype, { def(AST_Assign, function(tw, descend, compressor) { var node = this; var left = node.left; - if (node.operator == "=" && left.equivalent_to(node.right) && !left.has_side_effects(compressor)) { - node.right.walk(tw); - walk_prop(left); - node.__drop = true; - } else if (!(left instanceof AST_Destructured || left instanceof AST_SymbolRef)) { + var scan = left instanceof AST_Destructured || left instanceof AST_SymbolRef; + switch (node.operator) { + case "=": + if (left.equivalent_to(node.right) && !left.has_side_effects(compressor)) { + node.right.walk(tw); + walk_prop(left); + node.__drop = true; + return true; + } + if (scan) { + walk_assign(); + return true; + } mark_assignment_to_arguments(left); return; - } else switch (node.operator) { - case "=": - walk_assign(); - break; case "&&=": case "||=": case "??=": left.walk(tw); push(tw); - walk_assign(); + if (scan) { + walk_assign(); + } else { + mark_assignment_to_arguments(left); + node.right.walk(tw); + } pop(tw); - break; + return true; default: + if (!scan) { + mark_assignment_to_arguments(left); + return; + } var d = left.definition(); d.assignments++; var fixed = d.fixed; @@ -860,8 +873,8 @@ merge(Compressor.prototype, { left.walk(tw); d.fixed = false; } + return true; } - return true; function walk_prop(lhs) { if (lhs instanceof AST_Dot) { @@ -7229,9 +7242,15 @@ merge(Compressor.prototype, { } if (left.has_side_effects(compressor)) return this; var right = this.right; - this.write_only = !(lazy_op[this.operator.slice(0, -1)] && right.has_side_effects(compressor)); - if (!root_expr(left).is_constant_expression(compressor.find_parent(AST_Scope))) return this; - return right.drop_side_effect_free(compressor); + if (lazy_op[this.operator.slice(0, -1)]) { + this.write_only = !right.has_side_effects(compressor); + } else { + this.write_only = true; + if (root_expr(left).is_constant_expression(compressor.find_parent(AST_Scope))) { + return right.drop_side_effect_free(compressor); + } + } + return this; }); def(AST_Await, function(compressor) { if (!compressor.option("awaits")) return this; diff --git a/test/compress/assignments.js b/test/compress/assignments.js index 274a0d631f..db56229248 100644 --- a/test/compress/assignments.js +++ b/test/compress/assignments.js @@ -549,3 +549,43 @@ logical_side_effects: { expect_stdout: "PASS" node_version: ">=15" } + +issue_4815_1: { + options = { + evaluate: true, + reduce_vars: true, + toplevel: true, + unused: true, + } + input: { + var a = "PASS"; + 42..p &&= a = "FAIL"; + console.log(a); + } + expect: { + var a = "PASS"; + 42..p &&= a = "FAIL"; + console.log(a); + } + expect_stdout: "PASS" + node_version: ">=15" +} + +issue_4815_2: { + options = { + pure_getters: "strict", + side_effects: true, + } + input: { + var a = "PASS"; + 42..p &&= a = "FAIL"; + console.log(a); + } + expect: { + var a = "PASS"; + 42..p &&= a = "FAIL"; + console.log(a); + } + expect_stdout: "PASS" + node_version: ">=15" +}