@@ -972,13 +972,13 @@ merge(Compressor.prototype, {
|
|||||||
|| node instanceof AST_Try
|
|| node instanceof AST_Try
|
||||||
|| node instanceof AST_With
|
|| node instanceof AST_With
|
||||||
|| parent instanceof AST_For && node !== parent.init
|
|| parent instanceof AST_For && node !== parent.init
|
||||||
|| (side_effects || !replace_all)
|
|| !replace_all
|
||||||
&& (node instanceof AST_SymbolRef && !node.is_declared(compressor))) {
|
&& (node instanceof AST_SymbolRef && !node.is_declared(compressor))) {
|
||||||
abort = true;
|
abort = true;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
// Stop only if candidate is found within conditional branches
|
// 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_Binary && lazy_op(parent.operator) && parent.left !== node
|
||||||
|| parent instanceof AST_Conditional && parent.condition !== node
|
|| parent instanceof AST_Conditional && parent.condition !== node
|
||||||
|| parent instanceof AST_If && parent.condition !== node)) {
|
|| parent instanceof AST_If && parent.condition !== node)) {
|
||||||
@@ -1096,17 +1096,12 @@ merge(Compressor.prototype, {
|
|||||||
var stop_if_hit = null;
|
var stop_if_hit = null;
|
||||||
var lhs = get_lhs(candidate);
|
var lhs = get_lhs(candidate);
|
||||||
if (!lhs || is_lhs_read_only(lhs) || lhs.has_side_effects(compressor)) continue;
|
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
|
// Locate symbols which may execute code outside of scanning range
|
||||||
var lvalues = get_lvalues(candidate);
|
var lvalues = get_lvalues(candidate);
|
||||||
if (lhs instanceof AST_SymbolRef) lvalues[lhs.name] = false;
|
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 side_effects = value_has_side_effects(candidate);
|
||||||
|
var replace_all = replace_all_symbols();
|
||||||
var may_throw = candidate.may_throw(compressor);
|
var may_throw = candidate.may_throw(compressor);
|
||||||
var funarg = candidate.name instanceof AST_SymbolFunarg;
|
var funarg = candidate.name instanceof AST_SymbolFunarg;
|
||||||
var hit = funarg;
|
var hit = funarg;
|
||||||
@@ -1151,7 +1146,7 @@ merge(Compressor.prototype, {
|
|||||||
hit_index++;
|
hit_index++;
|
||||||
}
|
}
|
||||||
branch.expression = branch.expression.transform(scanner);
|
branch.expression = branch.expression.transform(scanner);
|
||||||
if (side_effects || !replace_all) break;
|
if (!replace_all) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
abort = true;
|
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) {
|
function value_has_side_effects(expr) {
|
||||||
if (expr instanceof AST_Unary) return false;
|
if (expr instanceof AST_Unary) return false;
|
||||||
return get_rvalue(expr).has_side_effects(compressor);
|
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) {
|
function may_modify(sym) {
|
||||||
var def = sym.definition();
|
var def = sym.definition();
|
||||||
if (def.orig.length == 1 && def.orig[0] instanceof AST_SymbolDefun) return false;
|
if (def.orig.length == 1 && def.orig[0] instanceof AST_SymbolDefun) return false;
|
||||||
|
|||||||
@@ -4517,3 +4517,32 @@ issue_2891_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: true
|
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"
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user