}
var lhs = is_lhs(node, parent);
if (lhs) return lhs;
+ if (level == 0 && value && value.is_constant()) return;
if (parent instanceof AST_Array) return is_modified(compressor, tw, parent, parent, level + 1);
+ if (parent instanceof AST_Assign) switch (parent.operator) {
+ case "=":
+ return is_modified(compressor, tw, parent, value, level + 1, immutable, recursive);
+ case "&&=":
+ case "||=":
+ case "??=":
+ return is_modified(compressor, tw, parent, parent, level + 1);
+ default:
+ return;
+ }
if (parent instanceof AST_Binary) {
if (!lazy_op[parent.operator]) return;
return is_modified(compressor, tw, parent, parent, level + 1);
if (def.fixed === undefined) return declare || all(def.orig, function(sym) {
return !(sym instanceof AST_SymbolLet);
});
- if (def.fixed === false) return false;
+ if (def.fixed === false || def.fixed === 0) return false;
var safe = tw.safe_ids[def.id];
if (def.safe_ids) {
def.safe_ids[def.id] = false;
}
var d = sym.definition();
d.assignments++;
- if (fixed && !modified && !sym.in_arg && safe_to_assign(tw, d)) {
+ if (!fixed || sym.in_arg || !safe_to_assign(tw, d)) {
+ walk();
+ d.fixed = false;
+ } else if (modified) {
+ walk();
+ d.fixed = 0;
+ } else {
push_ref(d, sym);
mark(tw, d);
if (left instanceof AST_Destructured
mark_escaped(tw, d, sym.scope, node, right, 0, 1);
sym.fixed = d.fixed = fixed;
sym.fixed.assigns = [ node ];
- } else {
- walk();
- d.fixed = false;
}
});
}
if (!safe) return;
safe.assign = true;
});
- if (d.fixed === false) {
+ if (d.fixed === false || d.fixed === 0) {
var redef = d.redefined();
if (redef && cross_scope(d.scope, this.scope)) redef.single_use = false;
} else if (d.fixed === undefined || !safe_to_read(tw, d)) {
if (d.single_use) {
d.single_use = "m";
} else {
- d.fixed = false;
+ d.fixed = 0;
}
}
if (d.fixed && tw.loop_ids[d.id] !== tw.in_loop) d.cross_loop = true;
AST_Symbol.DEFMETHOD("fixed_value", function() {
var fixed = this.definition().fixed;
+ if (fixed) {
+ if (this.fixed) fixed = this.fixed;
+ return fixed instanceof AST_Node ? fixed : fixed();
+ }
+ fixed = fixed === 0 && this.fixed;
if (!fixed) return fixed;
- if (this.fixed) fixed = this.fixed;
- return fixed instanceof AST_Node ? fixed : fixed();
+ var value = fixed instanceof AST_Node ? fixed : fixed();
+ return value.is_constant() && value;
});
AST_SymbolRef.DEFMETHOD("is_immutable", function() {
if (!(node.left instanceof AST_PropAccess)) return;
var sym = node.left.expression;
if (!(sym instanceof AST_SymbolRef)) return;
- if (!names[sym.name]) return;
+ if (!(sym.name in names)) return;
if (!node.right.is_constant_expression(scope)) return;
var prop = node.left.property;
if (prop instanceof AST_Node) {
- if (try_join(prop)) prop = node.left.property = prop.right;
+ if (try_join(prop)) prop = node.left.property = prop.right.clone();
prop = prop.evaluate(compressor);
}
if (prop instanceof AST_Node) return;
if (!all(value.properties, diff)) return;
value.properties.push(make_node(AST_ObjectKeyVal, node, {
key: prop,
- value: node.right
+ value: node.right,
}));
return true;
}