|| 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)) {
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;
hit_index++;
}
branch.expression = branch.expression.transform(scanner);
- if (side_effects || !replace_all) break;
+ if (!replace_all) break;
}
}
abort = true;
}));
}
+ 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;