diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2017-03-05 14:56:14 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-03-05 14:56:14 +0800 |
commit | 35a849dc48adf4a7318481f0ff540375ec0e43b2 (patch) | |
tree | 6a803e1f94d3963146ef21e034135c22f9de49bd | |
parent | b70591be1a603d3c1728e6563691c3a192023d3f (diff) | |
download | tracifyjs-35a849dc48adf4a7318481f0ff540375ec0e43b2.tar.gz tracifyjs-35a849dc48adf4a7318481f0ff540375ec0e43b2.zip |
collapse assignment with adjacent subsequent usage (#1553)
- consolidate `cascade` optimisations
- support ++/-- postfixes
- remove redundant optimisation identified in #1460
fixes #368
-rw-r--r-- | lib/compress.js | 43 | ||||
-rw-r--r-- | test/compress/issue-368.js | 41 |
2 files changed, 68 insertions, 16 deletions
diff --git a/lib/compress.js b/lib/compress.js index 1a54c75e..f1409d90 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -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; @@ -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; } @@ -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, { diff --git a/test/compress/issue-368.js b/test/compress/issue-368.js new file mode 100644 index 00000000..8c41a894 --- /dev/null +++ b/test/compress/issue-368.js @@ -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; + } + } +} |