collapse assignment with adjacent subsequent usage (#1553)
- consolidate `cascade` optimisations - support ++/-- postfixes - remove redundant optimisation identified in #1460 fixes #368
This commit is contained in:
@@ -607,10 +607,7 @@ merge(Compressor.prototype, {
|
|||||||
return statements;
|
return statements;
|
||||||
|
|
||||||
function is_lvalue(node, parent) {
|
function is_lvalue(node, parent) {
|
||||||
return node instanceof AST_SymbolRef && (
|
return node instanceof AST_SymbolRef && isLHS(node, parent);
|
||||||
(parent instanceof AST_Assign && node === parent.left)
|
|
||||||
|| (parent instanceof AST_Unary && parent.expression === node
|
|
||||||
&& (parent.operator == "++" || parent.operator == "--")));
|
|
||||||
}
|
}
|
||||||
function replace_var(node, parent, is_constant) {
|
function replace_var(node, parent, is_constant) {
|
||||||
if (is_lvalue(node, parent)) return node;
|
if (is_lvalue(node, parent)) return node;
|
||||||
@@ -1152,7 +1149,7 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function isLHS(node, parent) {
|
function isLHS(node, parent) {
|
||||||
return parent instanceof AST_Unary && (parent.operator === "++" || parent.operator === "--")
|
return parent instanceof AST_Unary && (parent.operator == "++" || parent.operator == "--")
|
||||||
|| parent instanceof AST_Assign && parent.left === node;
|
|| parent instanceof AST_Assign && parent.left === node;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2832,20 +2829,34 @@ merge(Compressor.prototype, {
|
|||||||
self.car = self.car.drop_side_effect_free(compressor, first_in_statement(compressor));
|
self.car = self.car.drop_side_effect_free(compressor, first_in_statement(compressor));
|
||||||
if (!self.car) return maintain_this_binding(compressor.parent(), self, self.cdr);
|
if (!self.car) return maintain_this_binding(compressor.parent(), self, self.cdr);
|
||||||
if (compressor.option("cascade")) {
|
if (compressor.option("cascade")) {
|
||||||
|
var left;
|
||||||
if (self.car instanceof AST_Assign
|
if (self.car instanceof AST_Assign
|
||||||
&& !self.car.left.has_side_effects(compressor)) {
|
&& !self.car.left.has_side_effects(compressor)) {
|
||||||
if (self.car.left.equivalent_to(self.cdr)) {
|
left = self.car.left;
|
||||||
return self.car;
|
} else if (self.car instanceof AST_UnaryPostfix
|
||||||
}
|
&& (self.car.operator == "++" || self.car.operator == "--")) {
|
||||||
if (self.cdr instanceof AST_Call
|
left = self.car.expression;
|
||||||
&& self.cdr.expression.equivalent_to(self.car.left)) {
|
|
||||||
self.cdr.expression = self.car;
|
|
||||||
return self.cdr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!self.car.has_side_effects(compressor)
|
if (left) {
|
||||||
&& self.car.equivalent_to(self.cdr)) {
|
var parent, field;
|
||||||
return self.car;
|
var cdr = self.cdr;
|
||||||
|
while (true) {
|
||||||
|
if (cdr.equivalent_to(left)) {
|
||||||
|
if (parent) {
|
||||||
|
parent[field] = self.car;
|
||||||
|
return self.cdr;
|
||||||
|
}
|
||||||
|
return self.car;
|
||||||
|
}
|
||||||
|
if (cdr instanceof AST_Binary && !(cdr instanceof AST_Assign)) {
|
||||||
|
field = cdr.left.is_constant() ? "right" : "left";
|
||||||
|
} else if (cdr instanceof AST_Call
|
||||||
|
|| cdr instanceof AST_Unary && cdr.operator != "++" && cdr.operator != "--") {
|
||||||
|
field = "expression";
|
||||||
|
} else break;
|
||||||
|
parent = cdr;
|
||||||
|
cdr = cdr[field];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (is_undefined(self.cdr)) {
|
if (is_undefined(self.cdr)) {
|
||||||
|
|||||||
41
test/compress/issue-368.js
Normal file
41
test/compress/issue-368.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
collapse: {
|
||||||
|
options = {
|
||||||
|
cascade: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f1() {
|
||||||
|
var a;
|
||||||
|
a = typeof b === 'function' ? b() : b;
|
||||||
|
return a !== undefined && c();
|
||||||
|
}
|
||||||
|
function f2(b) {
|
||||||
|
var a;
|
||||||
|
b = c();
|
||||||
|
a = typeof b === 'function' ? b() : b;
|
||||||
|
return 'stirng' == typeof a && d();
|
||||||
|
}
|
||||||
|
function f3(c) {
|
||||||
|
var a;
|
||||||
|
a = b(a / 2);
|
||||||
|
if (a < 0) {
|
||||||
|
c++;
|
||||||
|
return c / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f1() {
|
||||||
|
return void 0 !== ('function' === typeof b ? b() : b) && c();
|
||||||
|
}
|
||||||
|
function f2(b) {
|
||||||
|
return b = c(), 'stirng' == typeof ('function' === typeof b ? b() : b) && d();
|
||||||
|
}
|
||||||
|
function f3(c) {
|
||||||
|
var a;
|
||||||
|
if ((a = b(a / 2)) < 0) return c++ / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user