diff --git a/lib/compress.js b/lib/compress.js index c9357d29..abc1592a 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -2028,19 +2028,31 @@ Compressor.prototype.compress = function(node) { line: node.start.line, col: node.start.col, }); - if (candidate.TYPE == "Binary") return make_node(AST_Assign, candidate, { - operator: "=", - left: candidate.right.left, - right: make_node(AST_Conditional, candidate, { - condition: candidate.operator == "&&" ? candidate.left : candidate.left.negate(compressor), - consequent: candidate.right.right, - alternative: node, - }), - }); + if (candidate.TYPE == "Binary") { + update_symbols(candidate, node); + return make_node(AST_Assign, candidate, { + operator: "=", + left: candidate.right.left, + right: candidate.operator == "&&" ? make_node(AST_Conditional, candidate, { + condition: candidate.left, + consequent: candidate.right.right, + alternative: node, + }) : make_node(AST_Conditional, candidate, { + condition: candidate.left, + consequent: node, + alternative: candidate.right.right, + }), + }); + } if (candidate instanceof AST_UnaryPostfix) return make_node(AST_UnaryPrefix, candidate, { operator: candidate.operator, expression: lhs.fixed && lhs.definition().fixed ? lhs.fixed.to_prefix() : lhs, }); + if (candidate instanceof AST_UnaryPrefix) { + clear_write_only(candidate); + return candidate; + } + update_symbols(rvalue, node); if (candidate instanceof AST_VarDef) { var def = candidate.name.definition(); if (def.references.length - def.replaced == 1 && !compressor.exposed(def)) { @@ -2053,7 +2065,7 @@ Compressor.prototype.compress = function(node) { right: rvalue, }); } - clear_write_only(candidate); + clear_write_only(rvalue); var assign = candidate.clone(); assign.right = rvalue; return assign; @@ -3011,6 +3023,14 @@ Compressor.prototype.compress = function(node) { } } + function update_symbols(value, node) { + var scope = node.scope || find_scope(scanner) || block_scope; + value.walk(new TreeWalker(function(node) { + if (node instanceof AST_BlockScope) return true; + if (node instanceof AST_Symbol) node.scope = scope; + })); + } + function may_be_global(node) { if (node instanceof AST_SymbolRef) { node = node.fixed_value(); @@ -5927,16 +5947,6 @@ Compressor.prototype.compress = function(node) { var references = Object.create(null); var prev = Object.create(null); var tw = new TreeWalker(function(node, descend) { - if (node.variables) { - if (node instanceof AST_BlockStatement) { - var save_scope = segment.scope; - segment.scope = node; - descend(); - segment.scope = save_scope; - return true; - } - segment.scope = node; - } if (node instanceof AST_Assign) { var lhs = node.left; var rhs = node.right; @@ -6308,7 +6318,6 @@ Compressor.prototype.compress = function(node) { var refs = references[def.id]; if (!refs) return; if (refs.start.block !== seg.block) return references[def.id] = false; - sym.scope = seg.scope; refs.push(sym); refs.end = seg; if (def.id in prev) { @@ -6323,7 +6332,6 @@ Compressor.prototype.compress = function(node) { return references[def.id] = false; } else { var refs = declarations.get(def.id) || []; - sym.scope = seg.scope; refs.push(sym); references[def.id] = refs; if (!read) { diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js index 9e8622d6..4304b857 100644 --- a/test/compress/collapse_vars.js +++ b/test/compress/collapse_vars.js @@ -9014,6 +9014,27 @@ collapse_and_assign: { expect_stdout: "PASS" } +collapse_and_assign_property: { + options = { + collapse_vars: true, + pure_getters: "strict", + reduce_vars: true, + unused: true, + } + input: { + console.log(function f() { + f && (f.p = "PASS"); + return f.p; + }()); + } + expect: { + console.log(function f() { + return f.p = f ? "PASS" : f.p; + }()); + } + expect_stdout: "PASS" +} + collapse_or_assign: { options = { collapse_vars: true, @@ -9031,7 +9052,7 @@ collapse_or_assign: { var a = { p: "PASS", }; - log(a = !a.q ? a.p : a); + log(a = a.q ? a: a.p); } expect_stdout: "PASS" }