support logical assignment operators (#4813)
This commit is contained in:
@@ -821,35 +821,19 @@ merge(Compressor.prototype, {
|
||||
} else if (!(left instanceof AST_Destructured || left instanceof AST_SymbolRef)) {
|
||||
mark_assignment_to_arguments(left);
|
||||
return;
|
||||
} else if (node.operator == "=") {
|
||||
node.right.walk(tw);
|
||||
scan_declaration(tw, compressor, left, function() {
|
||||
return node.right;
|
||||
}, function(sym, fixed, walk) {
|
||||
if (!(sym instanceof AST_SymbolRef)) {
|
||||
mark_assignment_to_arguments(sym);
|
||||
walk();
|
||||
return;
|
||||
}
|
||||
var d = sym.definition();
|
||||
d.assignments++;
|
||||
if (fixed
|
||||
&& !is_modified(compressor, tw, node, node.right, 0)
|
||||
&& !sym.in_arg
|
||||
&& safe_to_assign(tw, d)) {
|
||||
push_ref(d, sym);
|
||||
mark(tw, d);
|
||||
if (d.single_use && left instanceof AST_Destructured) d.single_use = false;
|
||||
tw.loop_ids[d.id] = tw.in_loop;
|
||||
mark_escaped(tw, d, sym.scope, node, node.right, 0, 1);
|
||||
sym.fixed = d.fixed = fixed;
|
||||
sym.fixed.assigns = [ node ];
|
||||
} else {
|
||||
walk();
|
||||
d.fixed = false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
} else switch (node.operator) {
|
||||
case "=":
|
||||
walk_assign();
|
||||
break;
|
||||
case "&&=":
|
||||
case "||=":
|
||||
case "??=":
|
||||
left.walk(tw);
|
||||
push(tw);
|
||||
walk_assign();
|
||||
pop(tw);
|
||||
break;
|
||||
default:
|
||||
var d = left.definition();
|
||||
d.assignments++;
|
||||
var fixed = d.fixed;
|
||||
@@ -900,6 +884,36 @@ merge(Compressor.prototype, {
|
||||
lhs.walk(tw);
|
||||
}
|
||||
}
|
||||
|
||||
function walk_assign() {
|
||||
node.right.walk(tw);
|
||||
scan_declaration(tw, compressor, left, function() {
|
||||
return node.right;
|
||||
}, function(sym, fixed, walk) {
|
||||
if (!(sym instanceof AST_SymbolRef)) {
|
||||
mark_assignment_to_arguments(sym);
|
||||
walk();
|
||||
return;
|
||||
}
|
||||
var d = sym.definition();
|
||||
d.assignments++;
|
||||
if (fixed
|
||||
&& !is_modified(compressor, tw, node, node.right, 0)
|
||||
&& !sym.in_arg
|
||||
&& safe_to_assign(tw, d)) {
|
||||
push_ref(d, sym);
|
||||
mark(tw, d);
|
||||
if (d.single_use && left instanceof AST_Destructured) d.single_use = false;
|
||||
tw.loop_ids[d.id] = tw.in_loop;
|
||||
mark_escaped(tw, d, sym.scope, node, node.right, 0, 1);
|
||||
sym.fixed = d.fixed = fixed;
|
||||
sym.fixed.assigns = [ node ];
|
||||
} else {
|
||||
walk();
|
||||
d.fixed = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
def(AST_Binary, function(tw) {
|
||||
if (!lazy_op[this.operator]) return;
|
||||
@@ -1979,7 +1993,9 @@ merge(Compressor.prototype, {
|
||||
|
||||
function should_stop(node, parent) {
|
||||
if (node === rvalue) return true;
|
||||
if (parent instanceof AST_For) return node !== parent.init;
|
||||
if (parent instanceof AST_For) {
|
||||
if (node !== parent.init) return true;
|
||||
}
|
||||
if (node instanceof AST_Assign) {
|
||||
return node.operator != "=" && lhs.equivalent_to(node.left);
|
||||
}
|
||||
@@ -2014,7 +2030,8 @@ merge(Compressor.prototype, {
|
||||
}
|
||||
|
||||
function in_conditional(node, parent) {
|
||||
if (parent instanceof AST_Binary) return lazy_op[parent.operator] && parent.left !== node;
|
||||
if (parent instanceof AST_Assign) return parent.left !== node && lazy_op[parent.operator.slice(0, -1)];
|
||||
if (parent instanceof AST_Binary) return parent.left !== node && lazy_op[parent.operator];
|
||||
if (parent instanceof AST_Case) return parent.expression !== node;
|
||||
if (parent instanceof AST_Conditional) return parent.condition !== node;
|
||||
return parent instanceof AST_If && parent.condition !== node;
|
||||
@@ -7211,11 +7228,10 @@ merge(Compressor.prototype, {
|
||||
if (compressor.has_directive("use strict") && expr.is_constant()) return this;
|
||||
}
|
||||
if (left.has_side_effects(compressor)) return this;
|
||||
this.write_only = true;
|
||||
if (root_expr(left).is_constant_expression(compressor.find_parent(AST_Scope))) {
|
||||
return this.right.drop_side_effect_free(compressor);
|
||||
}
|
||||
return this;
|
||||
var right = this.right;
|
||||
this.write_only = !(lazy_op[this.operator.slice(0, -1)] && right.has_side_effects(compressor));
|
||||
if (!root_expr(left).is_constant_expression(compressor.find_parent(AST_Scope))) return this;
|
||||
return right.drop_side_effect_free(compressor);
|
||||
});
|
||||
def(AST_Await, function(compressor) {
|
||||
if (!compressor.option("awaits")) return this;
|
||||
|
||||
Reference in New Issue
Block a user