improve collapse_vars (#3103)
This commit is contained in:
@@ -980,24 +980,12 @@ merge(Compressor.prototype, {
|
||||
}
|
||||
// Stop immediately if these node types are encountered
|
||||
var parent = scanner.parent();
|
||||
if (node instanceof AST_Assign && node.operator != "=" && lhs.equivalent_to(node.left)
|
||||
|| node instanceof AST_Call && lhs instanceof AST_PropAccess && lhs.equivalent_to(node.expression)
|
||||
|| node instanceof AST_Debugger
|
||||
|| node instanceof AST_IterationStatement && !(node instanceof AST_For)
|
||||
|| node instanceof AST_LoopControl
|
||||
|| node instanceof AST_Try
|
||||
|| node instanceof AST_With
|
||||
|| parent instanceof AST_For && node !== parent.init
|
||||
|| !replace_all
|
||||
&& (node instanceof AST_SymbolRef && !node.is_declared(compressor))) {
|
||||
if (should_stop(node, parent)) {
|
||||
abort = true;
|
||||
return node;
|
||||
}
|
||||
// Stop only if candidate is found within conditional branches
|
||||
if (!stop_if_hit
|
||||
&& (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)) {
|
||||
if (!stop_if_hit && in_conditional(node, parent)) {
|
||||
stop_if_hit = parent;
|
||||
}
|
||||
// Replace variable with assignment when found
|
||||
@@ -1047,20 +1035,7 @@ merge(Compressor.prototype, {
|
||||
// These node types have child nodes that execute sequentially,
|
||||
// but are otherwise not safe to scan into or beyond them.
|
||||
var sym;
|
||||
if (node instanceof AST_Call
|
||||
|| node instanceof AST_Exit
|
||||
&& (side_effects || lhs instanceof AST_PropAccess || may_modify(lhs))
|
||||
|| node instanceof AST_PropAccess
|
||||
&& (side_effects || node.expression.may_throw_on_access(compressor))
|
||||
|| node instanceof AST_SymbolRef
|
||||
&& (symbol_in_lvalues(node) || side_effects && may_modify(node))
|
||||
|| node instanceof AST_This && symbol_in_lvalues(node)
|
||||
|| node instanceof AST_VarDef && node.value
|
||||
&& (node.name.name in lvalues || side_effects && may_modify(node.name))
|
||||
|| (sym = is_lhs(node.left, node))
|
||||
&& (sym instanceof AST_PropAccess || sym.name in lvalues)
|
||||
|| may_throw
|
||||
&& (in_try ? node.has_side_effects(compressor) : side_effects_external(node))) {
|
||||
if (is_last_node(node, parent) || may_throw(node)) {
|
||||
stop_after = node;
|
||||
if (node instanceof AST_Scope) abort = true;
|
||||
}
|
||||
@@ -1119,7 +1094,9 @@ merge(Compressor.prototype, {
|
||||
var lhs_local = is_lhs_local(lhs);
|
||||
if (!side_effects) 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) ? in_try ? function(node) {
|
||||
return node.has_side_effects(compressor);
|
||||
} : side_effects_external : return_false;
|
||||
var funarg = candidate.name instanceof AST_SymbolFunarg;
|
||||
var hit = funarg;
|
||||
var abort = false, replaced = 0, can_replace = !args || !hit;
|
||||
@@ -1171,6 +1148,51 @@ merge(Compressor.prototype, {
|
||||
}
|
||||
}
|
||||
|
||||
function should_stop(node, parent) {
|
||||
if (node instanceof AST_Assign) return node.operator != "=" && lhs.equivalent_to(node.left);
|
||||
if (node instanceof AST_Call) {
|
||||
return lhs instanceof AST_PropAccess && lhs.equivalent_to(node.expression);
|
||||
}
|
||||
if (node instanceof AST_Debugger) return true;
|
||||
if (node instanceof AST_IterationStatement) return !(node instanceof AST_For);
|
||||
if (node instanceof AST_LoopControl) return true;
|
||||
if (node instanceof AST_Try) return true;
|
||||
if (node instanceof AST_With) return true;
|
||||
if (parent instanceof AST_For) return node !== parent.init;
|
||||
if (replace_all) return false;
|
||||
return node instanceof AST_SymbolRef && !node.is_declared(compressor);
|
||||
}
|
||||
|
||||
function in_conditional(node, parent) {
|
||||
if (parent instanceof AST_Binary) return lazy_op[parent.operator] && parent.left !== node;
|
||||
if (parent instanceof AST_Conditional) return parent.condition !== node;
|
||||
return parent instanceof AST_If && parent.condition !== node;
|
||||
}
|
||||
|
||||
function is_last_node(node, parent) {
|
||||
if (node instanceof AST_Call) return true;
|
||||
if (node instanceof AST_Exit) {
|
||||
return side_effects || lhs instanceof AST_PropAccess || may_modify(lhs);
|
||||
}
|
||||
if (node instanceof AST_PropAccess) {
|
||||
return side_effects || node.expression.may_throw_on_access(compressor);
|
||||
}
|
||||
if (node instanceof AST_SymbolRef) {
|
||||
if (symbol_in_lvalues(node, parent)) {
|
||||
return !parent || parent.operator != "=" || parent.left !== node;
|
||||
}
|
||||
return side_effects && may_modify(node);
|
||||
}
|
||||
if (node instanceof AST_This) return symbol_in_lvalues(node, parent);
|
||||
if (node instanceof AST_VarDef) {
|
||||
if (!node.value) return false;
|
||||
return node.name.name in lvalues || side_effects && may_modify(node.name);
|
||||
}
|
||||
var sym = is_lhs(node.left, node);
|
||||
if (sym && sym.name in lvalues) return true;
|
||||
if (sym instanceof AST_PropAccess) return true;
|
||||
}
|
||||
|
||||
function extract_args() {
|
||||
var iife, fn = compressor.self();
|
||||
if (fn instanceof AST_Function
|
||||
@@ -1482,10 +1504,10 @@ merge(Compressor.prototype, {
|
||||
return false;
|
||||
}
|
||||
|
||||
function symbol_in_lvalues(sym) {
|
||||
function symbol_in_lvalues(sym, parent) {
|
||||
var lvalue = lvalues[sym.name];
|
||||
if (!lvalue) return;
|
||||
if (lvalue !== lhs) return true;
|
||||
if (lvalue !== lhs) return !(parent instanceof AST_Call);
|
||||
scan_rhs = false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user