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 = [];
|
||||||
var in_use_ids = Object.create(null); // avoid expensive linear scans of in_use
|
var in_use_ids = Object.create(null); // avoid expensive linear scans of in_use
|
||||||
var fixed_ids = Object.create(null);
|
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) {
|
if (self instanceof AST_Toplevel && compressor.top_retain) {
|
||||||
self.variables.each(function(def) {
|
self.variables.each(function(def) {
|
||||||
if (compressor.top_retain(def) && !(def.id in in_use_ids)) {
|
if (compressor.top_retain(def) && !(def.id in in_use_ids)) {
|
||||||
@@ -3381,6 +3383,17 @@ merge(Compressor.prototype, {
|
|||||||
);
|
);
|
||||||
self.transform(tt);
|
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) {
|
function scan_ref_scoped(node, descend) {
|
||||||
var node_def, props = [], sym = assign_as_unused(node, props);
|
var node_def, props = [], sym = assign_as_unused(node, props);
|
||||||
if (sym instanceof AST_SymbolRef
|
if (sym instanceof AST_SymbolRef
|
||||||
@@ -3390,9 +3403,19 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
if (node instanceof AST_Assign) {
|
if (node instanceof AST_Assign) {
|
||||||
node.right.walk(tw);
|
node.right.walk(tw);
|
||||||
if (node.left === sym && !node_def.chained && sym.fixed_value() === node.right) {
|
if (node.left === sym) {
|
||||||
|
if (!node_def.chained && sym.fixed_value() === node.right) {
|
||||||
fixed_ids[node_def.id] = node;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1785,3 +1785,32 @@ issue_805_2: {
|
|||||||
"bar",
|
"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