fix corner case in collapse_vars (#2909)

fixes #2908
This commit is contained in:
Alex Lam S.L
2018-02-13 01:41:22 +08:00
committed by GitHub
parent 0809699bdc
commit 0c4f315c02
2 changed files with 51 additions and 10 deletions

View File

@@ -972,13 +972,13 @@ merge(Compressor.prototype, {
|| node instanceof AST_Try
|| node instanceof AST_With
|| parent instanceof AST_For && node !== parent.init
|| (side_effects || !replace_all)
|| !replace_all
&& (node instanceof AST_SymbolRef && !node.is_declared(compressor))) {
abort = true;
return node;
}
// Stop only if candidate is found within conditional branches
if (!stop_if_hit && (side_effects || !replace_all)
if (!stop_if_hit && (!lhs_local || !replace_all)
&& (parent instanceof AST_Binary && lazy_op(parent.operator) && parent.left !== node
|| parent instanceof AST_Conditional && parent.condition !== node
|| parent instanceof AST_If && parent.condition !== node)) {
@@ -1096,17 +1096,12 @@ merge(Compressor.prototype, {
var stop_if_hit = null;
var lhs = get_lhs(candidate);
if (!lhs || is_lhs_read_only(lhs) || lhs.has_side_effects(compressor)) continue;
var lhs_local = is_lhs_local(lhs);
// Locate symbols which may execute code outside of scanning range
var lvalues = get_lvalues(candidate);
if (lhs instanceof AST_SymbolRef) lvalues[lhs.name] = false;
var replace_all = value_def;
if (!replace_all && lhs instanceof AST_SymbolRef) {
var def = lhs.definition();
if (def.references.length - def.replaced == (candidate instanceof AST_VarDef ? 1 : 2)) {
replace_all = true;
}
}
var side_effects = value_has_side_effects(candidate);
var replace_all = replace_all_symbols();
var may_throw = candidate.may_throw(compressor);
var funarg = candidate.name instanceof AST_SymbolFunarg;
var hit = funarg;
@@ -1151,7 +1146,7 @@ merge(Compressor.prototype, {
hit_index++;
}
branch.expression = branch.expression.transform(scanner);
if (side_effects || !replace_all) break;
if (!replace_all) break;
}
}
abort = true;
@@ -1393,11 +1388,28 @@ merge(Compressor.prototype, {
}));
}
function is_lhs_local(lhs) {
while (lhs instanceof AST_PropAccess) lhs = lhs.expression;
return lhs instanceof AST_SymbolRef && lhs.definition().scope === scope;
}
function value_has_side_effects(expr) {
if (expr instanceof AST_Unary) return false;
return get_rvalue(expr).has_side_effects(compressor);
}
function replace_all_symbols() {
if (side_effects) return false;
if (value_def) return true;
if (lhs instanceof AST_SymbolRef) {
var def = lhs.definition();
if (def.references.length - def.replaced == (candidate instanceof AST_VarDef ? 1 : 2)) {
return true;
}
}
return false;
}
function may_modify(sym) {
var def = sym.definition();
if (def.orig.length == 1 && def.orig[0] instanceof AST_SymbolDefun) return false;

View File

@@ -4517,3 +4517,32 @@ issue_2891_2: {
}
expect_stdout: true
}
issue_2908: {
options = {
collapse_vars: true,
}
input: {
var a = 0, b = 0;
function f(c) {
if (1 == c) return;
a++;
if (2 == c) b = a;
}
f(0);
f(2);
console.log(b);
}
expect: {
var a = 0, b = 0;
function f(c) {
if (1 == c) return;
a++;
if (2 == c) b = a;
}
f(0);
f(2);
console.log(b);
}
expect_stdout: "2"
}