diff --git a/lib/compress.js b/lib/compress.js index b02a116357..73c9d653cc 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -1886,8 +1886,7 @@ merge(Compressor.prototype, { if (is_lhs(node, multi_replacer.parent())) return node; var ref = rvalue.clone(); value_def.references.push(ref); - if (abort && candidate instanceof AST_Assign - && def.references.length - def.replaced - (assignments[def.name] || 0) > 1) { + if (abort && candidate instanceof AST_Assign && remaining_refs(def) > 1) { return make_node(AST_Assign, candidate, { operator: "=", left: node, @@ -2281,7 +2280,9 @@ merge(Compressor.prototype, { if (!(lhs instanceof AST_Destructured)) candidates.push(hit_stack.slice()); extract_candidates(lhs); extract_candidates(expr.right); - if (lhs instanceof AST_SymbolRef) assignments[lhs.name] = (assignments[lhs.name] || 0) + 1; + if (lhs instanceof AST_SymbolRef && expr.operator == "=") { + assignments[lhs.name] = (assignments[lhs.name] || 0) + 1; + } } else if (expr instanceof AST_Await) { extract_candidates(expr.expression, unused); } else if (expr instanceof AST_Binary) { @@ -2584,6 +2585,10 @@ merge(Compressor.prototype, { return value_def = def; } + function remaining_refs(def) { + return def.references.length - def.replaced - (assignments[def.name] || 0); + } + function get_lhs(expr) { if (expr instanceof AST_Assign) { var lhs = expr.left; @@ -2592,7 +2597,7 @@ merge(Compressor.prototype, { var def = lhs.definition(); if (scope.uses_arguments && is_funarg(def)) return lhs; if (compressor.exposed(def)) return lhs; - remaining = def.references.length - def.replaced - (assignments[def.name] || 0); + remaining = remaining_refs(def); if (def.fixed && lhs.fixed) remaining = Math.min(remaining, def.references.filter(function(ref) { return ref.fixed === lhs.fixed; }).length - 1); @@ -2608,7 +2613,7 @@ merge(Compressor.prototype, { if (!member(lhs, def.orig)) return; if (scope.uses_arguments && is_funarg(def)) return; var declared = def.orig.length - def.eliminated - (declare_only[def.name] || 0); - remaining = def.references.length - def.replaced - (assignments[def.name] || 0); + remaining = remaining_refs(def); if (def.fixed) remaining = Math.min(remaining, def.references.filter(function(ref) { if (!ref.fixed) return true; if (!ref.fixed.assigns) return true; diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js index 3ac8894afa..f8a8a31aba 100644 --- a/test/compress/collapse_vars.js +++ b/test/compress/collapse_vars.js @@ -8560,7 +8560,7 @@ issue_4047_1: { expect: { var b = 1; var a; - console.log((a = --b + ((a = 0) !== typeof A), +void ((a >>= 0) && console.log("PASS")))); + console.log((a = --b + (0 !== typeof A), +void ((a >>= 0) && console.log("PASS")))); } expect_stdout: [ "PASS", @@ -9085,3 +9085,25 @@ issue_4891: { "0", ] } + +issue_4895: { + options = { + collapse_vars: true, + toplevel: true, + } + input: { + var a, b; + (function f() { + a = 42; + })(); + console.log((b = a) || b, b += 0); + } + expect: { + var a, b; + (function f() { + a = 42; + })(); + console.log((b = a) || b, b += 0); + } + expect_stdout: "42 42" +}