preserve non-constant value assignments with modifications (#2997)
fixes #2995
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user