private accounting for collapse_vars

- avoid issues with identity reference due to deep cloning

fixes #2437
This commit is contained in:
alexlamsl 2017-11-06 02:58:01 +08:00
parent 02fc19d4e4
commit f0cef8d631
2 changed files with 64 additions and 15 deletions

View File

@ -788,6 +788,14 @@ merge(Compressor.prototype, {
|| compressor.option("unsafe") && global_names(this.name); || compressor.option("unsafe") && global_names(this.name);
}); });
function drop_decl(def) {
def._eliminiated = (def._eliminiated || 0) + 1;
if (def.orig.length == def._eliminiated) {
def.scope.functions.del(def.name);
def.scope.variables.del(def.name);
}
}
function tighten_body(statements, compressor) { function tighten_body(statements, compressor) {
var CHANGED, max_iter = 10; var CHANGED, max_iter = 10;
do { do {
@ -1000,7 +1008,8 @@ merge(Compressor.prototype, {
function get_lhs(expr) { function get_lhs(expr) {
if (expr instanceof AST_VarDef) { if (expr instanceof AST_VarDef) {
var def = expr.name.definition(); var def = expr.name.definition();
if (def.orig.length > 1 && !(expr.name instanceof AST_SymbolFunarg) if (def.orig.length - (def._eliminiated || 0) > 1
&& !(expr.name instanceof AST_SymbolFunarg)
|| def.references.length == 1 && !compressor.exposed(def)) { || def.references.length == 1 && !compressor.exposed(def)) {
return make_node(AST_SymbolRef, expr.name, expr.name); return make_node(AST_SymbolRef, expr.name, expr.name);
} }
@ -1047,7 +1056,7 @@ merge(Compressor.prototype, {
if (node === expr) { if (node === expr) {
found = true; found = true;
if (node instanceof AST_VarDef) { if (node instanceof AST_VarDef) {
remove(node.name.definition().orig, node.name); drop_decl(node.name.definition());
node.value = null; node.value = null;
return node; return node;
} }
@ -2420,7 +2429,7 @@ merge(Compressor.prototype, {
var def = node.name.definition(); var def = node.name.definition();
if (!(def.id in in_use_ids)) { if (!(def.id in in_use_ids)) {
compressor[node.name.unreferenced() ? "warn" : "info"]("Dropping unused function {name} [{file}:{line},{col}]", template(node.name)); compressor[node.name.unreferenced() ? "warn" : "info"]("Dropping unused function {name} [{file}:{line},{col}]", template(node.name));
drop_decl(def, node.name); drop_decl(def);
return make_node(AST_EmptyStatement, node); return make_node(AST_EmptyStatement, node);
} }
return node; return node;
@ -2442,7 +2451,7 @@ merge(Compressor.prototype, {
if (var_defs.length > 1 && !def.value) { if (var_defs.length > 1 && !def.value) {
compressor.warn("Dropping duplicated definition of variable {name} [{file}:{line},{col}]", template(def.name)); compressor.warn("Dropping duplicated definition of variable {name} [{file}:{line},{col}]", template(def.name));
remove(var_defs, def); remove(var_defs, def);
drop_decl(sym, def.name); drop_decl(sym);
return; return;
} }
} }
@ -2475,7 +2484,7 @@ merge(Compressor.prototype, {
} else { } else {
compressor[def.name.unreferenced() ? "warn" : "info"]("Dropping unused variable {name} [{file}:{line},{col}]", template(def.name)); compressor[def.name.unreferenced() ? "warn" : "info"]("Dropping unused variable {name} [{file}:{line},{col}]", template(def.name));
} }
drop_decl(sym, def.name); drop_decl(sym);
} }
}); });
if (head.length == 0 && tail.length == 1 && tail[0].name instanceof AST_SymbolVar) { if (head.length == 0 && tail.length == 1 && tail[0].name instanceof AST_SymbolVar) {
@ -2484,7 +2493,7 @@ merge(Compressor.prototype, {
var def = tail.pop(); var def = tail.pop();
compressor.warn("Converting duplicated definition of variable {name} to assignment [{file}:{line},{col}]", template(def.name)); compressor.warn("Converting duplicated definition of variable {name} to assignment [{file}:{line},{col}]", template(def.name));
remove(var_defs, def); remove(var_defs, def);
drop_decl(def.name.definition(), def.name); drop_decl(def.name.definition());
side_effects.unshift(make_node(AST_Assign, def, { side_effects.unshift(make_node(AST_Assign, def, {
operator: "=", operator: "=",
left: make_node(AST_SymbolRef, def.name, def.name), left: make_node(AST_SymbolRef, def.name, def.name),
@ -2566,14 +2575,6 @@ merge(Compressor.prototype, {
col : sym.start.col col : sym.start.col
}; };
} }
function drop_decl(def, decl) {
remove(def.orig, decl);
if (!def.orig.length) {
def.scope.functions.del(def.name);
def.scope.variables.del(def.name);
}
}
} }
); );
self.transform(tt); self.transform(tt);
@ -3293,7 +3294,7 @@ merge(Compressor.prototype, {
})); }));
if (reduce_vars) name.definition().fixed = false; if (reduce_vars) name.definition().fixed = false;
} }
remove(def.name.definition().orig, def.name); drop_decl(def.name.definition());
return a; return a;
}, []); }, []);
if (assignments.length == 0) return null; if (assignments.length == 0) return null;

View File

@ -3029,3 +3029,51 @@ issue_2425_3: {
} }
expect_stdout: "15" expect_stdout: "15"
} }
issue_2437: {
options = {
collapse_vars: true,
conditionals: true,
inline: true,
join_vars: true,
reduce_vars: true,
side_effects: true,
sequences: true,
toplevel: true,
unused: true,
}
input: {
function foo() {
bar();
}
function bar() {
if (xhrDesc) {
var req = new XMLHttpRequest();
var result = !!req.onreadystatechange;
Object.defineProperty(XMLHttpRequest.prototype, 'onreadystatechange', xhrDesc || {});
return result;
}
else {
var req = new XMLHttpRequest();
var detectFunc = function () { };
req.onreadystatechange = detectFunc;
var result = req[SYMBOL_FAKE_ONREADYSTATECHANGE_1] === detectFunc;
req.onreadystatechange = null;
return result;
}
}
foo();
}
expect: {
!function() {
if (xhrDesc)
return result = !!(req = new XMLHttpRequest()).onreadystatechange,
Object.defineProperty(XMLHttpRequest.prototype, "onreadystatechange", xhrDesc || {}),
result;
var req = new XMLHttpRequest(), detectFunc = function() {};
req.onreadystatechange = detectFunc;
var result = req[SYMBOL_FAKE_ONREADYSTATECHANGE_1] === detectFunc;
req.onreadystatechange = null;
}();
}
}