diff options
-rw-r--r-- | lib/compress.js | 27 | ||||
-rw-r--r-- | test/compress/drop-unused.js | 29 |
2 files changed, 54 insertions, 2 deletions
diff --git a/lib/compress.js b/lib/compress.js index 1b52f83e..cacffd37 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -3114,6 +3114,8 @@ merge(Compressor.prototype, { var in_use = []; var in_use_ids = Object.create(null); // avoid expensive linear scans of in_use var fixed_ids = Object.create(null); + var value_read = Object.create(null); + var value_modified = Object.create(null); if (self instanceof AST_Toplevel && compressor.top_retain) { self.variables.each(function(def) { if (compressor.top_retain(def) && !(def.id in in_use_ids)) { @@ -3381,6 +3383,17 @@ merge(Compressor.prototype, { ); self.transform(tt); + function verify_safe_usage(def, read, modified) { + if (def.id in in_use_ids) return; + if (read && modified) { + in_use_ids[def.id] = true; + in_use.push(def); + } else { + value_read[def.id] = read; + value_modified[def.id] = modified; + } + } + function scan_ref_scoped(node, descend) { var node_def, props = [], sym = assign_as_unused(node, props); if (sym instanceof AST_SymbolRef @@ -3390,8 +3403,18 @@ merge(Compressor.prototype, { }); if (node instanceof AST_Assign) { node.right.walk(tw); - if (node.left === sym && !node_def.chained && sym.fixed_value() === node.right) { - fixed_ids[node_def.id] = node; + if (node.left === sym) { + if (!node_def.chained && sym.fixed_value() === node.right) { + fixed_ids[node_def.id] = node; + } + if (!node.write_only) { + verify_safe_usage(node_def, true, value_modified[node_def.id]); + } + } else { + var fixed = sym.fixed_value(); + if (!fixed || !fixed.is_constant()) { + verify_safe_usage(node_def, value_read[node_def.id], true); + } } } return true; diff --git a/test/compress/drop-unused.js b/test/compress/drop-unused.js index ee8e6c0c..301bff1c 100644 --- a/test/compress/drop-unused.js +++ b/test/compress/drop-unused.js @@ -1785,3 +1785,32 @@ issue_805_2: { "bar", ] } + +issue_2995: { + options = { + pure_getters: "strict", + reduce_vars: true, + unused: true, + } + input: { + function f(a) { + var b; + a.b = b = function() {}; + b.c = "PASS"; + } + var o = {}; + f(o); + console.log(o.b.c); + } + expect: { + function f(a) { + var b; + a.b = b = function() {}; + b.c = "PASS"; + } + var o = {}; + f(o); + console.log(o.b.c); + } + expect_stdout: "PASS" +} |