}
var lhs = is_lhs(node, parent);
if (lhs) return lhs;
- if (!immutable
- && parent instanceof AST_Call
- && parent.expression === node
- && !parent.is_expr_pure(compressor)
- && (!(value instanceof AST_Function)
- || !(parent instanceof AST_New) && value.contains_this())) {
- return true;
- }
- if (parent instanceof AST_Array) {
- return is_modified(compressor, tw, parent, parent, level + 1);
- }
- if (parent instanceof AST_ObjectKeyVal && node === parent.value) {
+ if (parent instanceof AST_Array) return is_modified(compressor, tw, parent, parent, level + 1);
+ if (parent instanceof AST_Call) {
+ return !immutable
+ && parent.expression === node
+ && !parent.is_expr_pure(compressor)
+ && (!(value instanceof AST_Function)
+ || !(parent instanceof AST_New) && value.contains_this());
+ }
+ if (parent instanceof AST_ForIn) return parent.init === node;
+ if (parent instanceof AST_ObjectKeyVal) {
+ if (parent.value !== node) return;
var obj = tw.parent(level + 1);
return is_modified(compressor, tw, obj, obj, level + 2);
}
- if (parent instanceof AST_PropAccess && parent.expression === node) {
+ if (parent instanceof AST_PropAccess) {
+ if (parent.expression !== node) return;
var prop = read_property(value, parent);
return (!immutable || recursive) && is_modified(compressor, tw, parent, prop, level + 1);
}
|| value instanceof AST_This;
}
+ function has_escaped(d, node, parent) {
+ if (parent instanceof AST_Assign) return parent.operator == "=" && parent.right === node;
+ if (parent instanceof AST_Call) return parent.expression !== node || parent instanceof AST_New;
+ if (parent instanceof AST_Exit) return parent.value === node && node.scope !== d.scope;
+ if (parent instanceof AST_VarDef) return parent.value === node;
+ }
+
+ function value_in_use(node, parent) {
+ if (parent instanceof AST_Array) return true;
+ if (parent instanceof AST_Binary) return lazy_op[parent.operator];
+ if (parent instanceof AST_Conditional) return parent.condition !== node;
+ if (parent instanceof AST_Sequence) return parent.tail_node() === node;
+ }
+
function mark_escaped(tw, d, scope, node, value, level, depth) {
var parent = tw.parent(level);
if (value && value.is_constant()) return;
- if (parent instanceof AST_Assign && parent.operator == "=" && node === parent.right
- || parent instanceof AST_Call && (node !== parent.expression || parent instanceof AST_New)
- || parent instanceof AST_Exit && node === parent.value && node.scope !== d.scope
- || parent instanceof AST_VarDef && node === parent.value) {
+ if (has_escaped(d, node, parent)) {
d.escaped.push(parent);
if (depth > 1 && !(value && value.is_constant_expression(scope))) depth = 1;
if (!d.escaped.depth || d.escaped.depth > depth) d.escaped.depth = depth;
return;
- } else if (parent instanceof AST_Array
- || parent instanceof AST_Binary && lazy_op[parent.operator]
- || parent instanceof AST_Conditional && node !== parent.condition
- || parent instanceof AST_Sequence && node === parent.tail_node()) {
+ } else if (value_in_use(node, parent)) {
mark_escaped(tw, d, scope, parent, parent, level + 1, depth);
- } else if (parent instanceof AST_ObjectKeyVal && node === parent.value) {
+ } else if (parent instanceof AST_ObjectKeyVal && parent.value === node) {
var obj = tw.parent(level + 1);
mark_escaped(tw, d, scope, obj, obj, level + 2, depth);
- } else if (parent instanceof AST_PropAccess && node === parent.expression) {
+ } else if (parent instanceof AST_PropAccess && parent.expression === node) {
value = read_property(value, parent);
mark_escaped(tw, d, scope, parent, value, level + 1, depth + 1);
if (value) return;
}
if (level > 0) return;
- if (parent instanceof AST_Call && node === parent.expression) return;
- if (parent instanceof AST_Sequence && node !== parent.tail_node()) return;
+ if (parent instanceof AST_Call && parent.expression === node) return;
+ if (parent instanceof AST_Sequence && parent.tail_node() !== node) return;
if (parent instanceof AST_SimpleStatement) return;
if (parent instanceof AST_Unary && !unary_side_effects[parent.operator]) return;
d.direct_access = true;
push(tw);
var init = this.init;
init.walk(tw);
- if (init instanceof AST_Var) {
- init = init.definitions[0].name;
- } else while (init instanceof AST_PropAccess) {
- init = init.expression.tail_node();
+ if (init instanceof AST_SymbolRef) {
+ init.definition().fixed = false;
+ } else if (init instanceof AST_Var) {
+ init.definitions[0].name.definition().fixed = false;
}
- var def = init.definition();
- if (def) def.fixed = false;
this.body.walk(tw);
pop(tw);
tw.in_loop = saved_loop;