Skip to content

Commit

Permalink
collapse assignment with adjacent subsequent usage (#1553)
Browse files Browse the repository at this point in the history
- consolidate `cascade` optimisations
- support ++/-- postfixes
- remove redundant optimisation identified in #1460

fixes #368
  • Loading branch information
alexlamsl authored Mar 5, 2017
1 parent b70591b commit 35a849d
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 16 deletions.
43 changes: 27 additions & 16 deletions lib/compress.js
Original file line number Diff line number Diff line change
Expand Up @@ -607,10 +607,7 @@ merge(Compressor.prototype, {
return statements;

function is_lvalue(node, parent) {
return node instanceof AST_SymbolRef && (
(parent instanceof AST_Assign && node === parent.left)
|| (parent instanceof AST_Unary && parent.expression === node
&& (parent.operator == "++" || parent.operator == "--")));
return node instanceof AST_SymbolRef && isLHS(node, parent);
}
function replace_var(node, parent, is_constant) {
if (is_lvalue(node, parent)) return node;
Expand Down Expand Up @@ -1152,7 +1149,7 @@ merge(Compressor.prototype, {
});

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;
}

Expand Down Expand Up @@ -2832,21 +2829,35 @@ merge(Compressor.prototype, {
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 (compressor.option("cascade")) {
var left;
if (self.car instanceof AST_Assign
&& !self.car.left.has_side_effects(compressor)) {
if (self.car.left.equivalent_to(self.cdr)) {
return self.car;
}
if (self.cdr instanceof AST_Call
&& self.cdr.expression.equivalent_to(self.car.left)) {
self.cdr.expression = self.car;
return self.cdr;
left = self.car.left;
} else if (self.car instanceof AST_UnaryPostfix
&& (self.car.operator == "++" || self.car.operator == "--")) {
left = self.car.expression;
}
if (left) {
var parent, field;
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 (!self.car.has_side_effects(compressor)
&& self.car.equivalent_to(self.cdr)) {
return self.car;
}
}
if (is_undefined(self.cdr)) {
return make_node(AST_UnaryPrefix, self, {
Expand Down
41 changes: 41 additions & 0 deletions test/compress/issue-368.js
Original file line number Diff line number Diff line change
@@ -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;
}
}
}

0 comments on commit 35a849d

Please sign in to comment.