diff --git a/lib/compress.js b/lib/compress.js index c75531cf..05f83701 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -2058,6 +2058,11 @@ Compressor.prototype.compress = function(node) { assign.right = rvalue; return assign; } + // Stop signals related to AST_SymbolRef + if (should_stop_ref(node, parent)) { + abort = true; + return node; + } // These node types have child nodes that execute sequentially, // but are otherwise not safe to scan into or beyond them. if (is_last_node(node, parent) || may_throw(node)) { @@ -2184,7 +2189,8 @@ Compressor.prototype.compress = function(node) { var stop_if_hit = null; var lhs = get_lhs(candidate); var side_effects = lhs && lhs.has_side_effects(compressor); - var scan_lhs = lhs && !side_effects && !is_lhs_read_only(lhs, compressor); + var scan_lhs = lhs && (!side_effects || lhs instanceof AST_SymbolRef) + && !is_lhs_read_only(lhs, compressor); var scan_rhs = foldable(candidate); if (!scan_lhs && !scan_rhs) continue; var compound = candidate instanceof AST_Assign && candidate.operator.slice(0, -1); @@ -2318,25 +2324,27 @@ Compressor.prototype.compress = function(node) { if (node instanceof AST_DestructuredKeyVal) return node.key instanceof AST_Node; if (node instanceof AST_DWLoop) return true; if (node instanceof AST_LoopControl) return true; - if (node instanceof AST_SymbolRef) { - if (node.is_declared(compressor)) { - if (node.fixed_value()) return false; - if (can_drop_symbol(node)) { - return !(parent instanceof AST_PropAccess && parent.expression === node) - && is_arguments(node.definition()); - } - } else if (is_direct_assignment(node, parent)) { - return false; - } - if (!replace_all) return true; - scan_rhs = false; - return false; - } if (node instanceof AST_Try) return true; if (node instanceof AST_With) return true; return false; } + function should_stop_ref(node, parent) { + if (!(node instanceof AST_SymbolRef)) return false; + if (node.is_declared(compressor)) { + if (node.fixed_value()) return false; + if (can_drop_symbol(node)) { + return !(parent instanceof AST_PropAccess && parent.expression === node) + && is_arguments(node.definition()); + } + } else if (is_direct_assignment(node, parent)) { + return false; + } + if (!replace_all) return true; + scan_rhs = false; + return false; + } + function in_conditional(node, parent) { if (parent instanceof AST_Assign) return parent.left !== node && lazy_op[parent.operator.slice(0, -1)]; if (parent instanceof AST_Binary) return parent.left !== node && lazy_op[parent.operator]; diff --git a/test/compress/assignments.js b/test/compress/assignments.js index 84904102..7db38674 100644 --- a/test/compress/assignments.js +++ b/test/compress/assignments.js @@ -673,8 +673,7 @@ issue_4827_1: { c &&= b = a, console.log(b); } expect: { - A = "FAIL"; - var a = A, b = "PASS", c; + var a = A = "FAIL", b = "PASS", c; c &&= b = a, console.log(b); } expect_stdout: "PASS" diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js index 126d4cf8..9e8622d6 100644 --- a/test/compress/collapse_vars.js +++ b/test/compress/collapse_vars.js @@ -2579,7 +2579,7 @@ side_effects_property: { expect_stdout: true } -undeclared: { +undeclared_1: { options = { collapse_vars: true, unused: true, @@ -2594,8 +2594,68 @@ undeclared: { } expect: { function f(x, y) { + return (b = y) + x; + } + } +} + +undeclared_2: { + options = { + collapse_vars: true, + unused: true, + } + input: { + function f(x, y) { + var a; + a = x; b = y; - return b + x; + return a + b; + } + } + expect: { + function f(x, y) { + return x + (b = y); + } + } +} + +undeclared_3: { + options = { + collapse_vars: true, + unused: true, + } + input: { + function f(x, y) { + var a; + a = x; + b = y; + return b + a(); + } + } + expect: { + function f(x, y) { + return (b = y) + x(); + } + } +} + +undeclared_4: { + options = { + collapse_vars: true, + unused: true, + } + input: { + function f(x, y) { + var a; + a = x; + b = y; + return a() + b; + } + } + expect: { + function f(x, y) { + b = y; + return x() + b; } } } @@ -2987,9 +3047,8 @@ compound_assignment_4: { console.log(a); } expect: { - A = "PASS"; var a = ""; - (a += (a = "FAIL", A)).p; + (a += (a = "FAIL", A = "PASS")).p; console.log(a); } expect_stdout: "PASS" diff --git a/test/compress/hoist_vars.js b/test/compress/hoist_vars.js index b9b72c54..626300e3 100644 --- a/test/compress/hoist_vars.js +++ b/test/compress/hoist_vars.js @@ -250,8 +250,7 @@ issue_4517: { expect: { console.log(function() { var a = 2; - A = a; - return A + typeof !1; + return (A = a) + typeof !1; }()); } expect_stdout: "2boolean"