Skip to content

Commit 35a849d

Browse files
authoredMar 5, 2017
collapse assignment with adjacent subsequent usage (#1553)
- consolidate `cascade` optimisations - support ++/-- postfixes - remove redundant optimisation identified in #1460 fixes #368
1 parent b70591b commit 35a849d

File tree

2 files changed

+68
-16
lines changed

2 files changed

+68
-16
lines changed
 

‎lib/compress.js

+27-16
Original file line numberDiff line numberDiff line change
@@ -607,10 +607,7 @@ merge(Compressor.prototype, {
607607
return statements;
608608

609609
function is_lvalue(node, parent) {
610-
return node instanceof AST_SymbolRef && (
611-
(parent instanceof AST_Assign && node === parent.left)
612-
|| (parent instanceof AST_Unary && parent.expression === node
613-
&& (parent.operator == "++" || parent.operator == "--")));
610+
return node instanceof AST_SymbolRef && isLHS(node, parent);
614611
}
615612
function replace_var(node, parent, is_constant) {
616613
if (is_lvalue(node, parent)) return node;
@@ -1152,7 +1149,7 @@ merge(Compressor.prototype, {
11521149
});
11531150

11541151
function isLHS(node, parent) {
1155-
return parent instanceof AST_Unary && (parent.operator === "++" || parent.operator === "--")
1152+
return parent instanceof AST_Unary && (parent.operator == "++" || parent.operator == "--")
11561153
|| parent instanceof AST_Assign && parent.left === node;
11571154
}
11581155

@@ -2832,21 +2829,35 @@ merge(Compressor.prototype, {
28322829
self.car = self.car.drop_side_effect_free(compressor, first_in_statement(compressor));
28332830
if (!self.car) return maintain_this_binding(compressor.parent(), self, self.cdr);
28342831
if (compressor.option("cascade")) {
2832+
var left;
28352833
if (self.car instanceof AST_Assign
28362834
&& !self.car.left.has_side_effects(compressor)) {
2837-
if (self.car.left.equivalent_to(self.cdr)) {
2838-
return self.car;
2839-
}
2840-
if (self.cdr instanceof AST_Call
2841-
&& self.cdr.expression.equivalent_to(self.car.left)) {
2842-
self.cdr.expression = self.car;
2843-
return self.cdr;
2835+
left = self.car.left;
2836+
} else if (self.car instanceof AST_UnaryPostfix
2837+
&& (self.car.operator == "++" || self.car.operator == "--")) {
2838+
left = self.car.expression;
2839+
}
2840+
if (left) {
2841+
var parent, field;
2842+
var cdr = self.cdr;
2843+
while (true) {
2844+
if (cdr.equivalent_to(left)) {
2845+
if (parent) {
2846+
parent[field] = self.car;
2847+
return self.cdr;
2848+
}
2849+
return self.car;
2850+
}
2851+
if (cdr instanceof AST_Binary && !(cdr instanceof AST_Assign)) {
2852+
field = cdr.left.is_constant() ? "right" : "left";
2853+
} else if (cdr instanceof AST_Call
2854+
|| cdr instanceof AST_Unary && cdr.operator != "++" && cdr.operator != "--") {
2855+
field = "expression";
2856+
} else break;
2857+
parent = cdr;
2858+
cdr = cdr[field];
28442859
}
28452860
}
2846-
if (!self.car.has_side_effects(compressor)
2847-
&& self.car.equivalent_to(self.cdr)) {
2848-
return self.car;
2849-
}
28502861
}
28512862
if (is_undefined(self.cdr)) {
28522863
return make_node(AST_UnaryPrefix, self, {

‎test/compress/issue-368.js

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
collapse: {
2+
options = {
3+
cascade: true,
4+
sequences: true,
5+
side_effects: true,
6+
unused: true,
7+
}
8+
input: {
9+
function f1() {
10+
var a;
11+
a = typeof b === 'function' ? b() : b;
12+
return a !== undefined && c();
13+
}
14+
function f2(b) {
15+
var a;
16+
b = c();
17+
a = typeof b === 'function' ? b() : b;
18+
return 'stirng' == typeof a && d();
19+
}
20+
function f3(c) {
21+
var a;
22+
a = b(a / 2);
23+
if (a < 0) {
24+
c++;
25+
return c / 2;
26+
}
27+
}
28+
}
29+
expect: {
30+
function f1() {
31+
return void 0 !== ('function' === typeof b ? b() : b) && c();
32+
}
33+
function f2(b) {
34+
return b = c(), 'stirng' == typeof ('function' === typeof b ? b() : b) && d();
35+
}
36+
function f3(c) {
37+
var a;
38+
if ((a = b(a / 2)) < 0) return c++ / 2;
39+
}
40+
}
41+
}

0 commit comments

Comments
 (0)
Please sign in to comment.