diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2020-01-28 07:33:11 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-28 07:33:11 +0800 |
commit | e9e76dcf040d5076b6046d7273c3509df106fb84 (patch) | |
tree | afe9ded11df559969c75abcb106f6bc040f3a306 /lib | |
parent | 0dcedad2d5a6b670ecd5aef3cf18d5e511af6e91 (diff) | |
download | tracifyjs-e9e76dcf040d5076b6046d7273c3509df106fb84.tar.gz tracifyjs-e9e76dcf040d5076b6046d7273c3509df106fb84.zip |
fix corner case in string concatenations (#3692)
- migrate de-facto compression to `conditionals` & `strings`
fixes #3689
Diffstat (limited to 'lib')
-rw-r--r-- | lib/compress.js | 54 |
1 files changed, 33 insertions, 21 deletions
diff --git a/lib/compress.js b/lib/compress.js index 4e967aef..e14d9d06 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -83,6 +83,7 @@ function Compressor(options, false_by_default) { reduce_vars : !false_by_default, sequences : !false_by_default, side_effects : !false_by_default, + strings : !false_by_default, switches : !false_by_default, top_retain : null, toplevel : !!(options && options["top_retain"]), @@ -6188,6 +6189,18 @@ merge(Compressor.prototype, { self.right = tmp; } } + function swap_chain() { + var rhs = self.right; + self.left = make_node(AST_Binary, self, { + operator: self.operator, + left: self.left, + right: rhs.left, + start: self.left.start, + end: rhs.left.end + }); + self.right = rhs.right; + self.left = self.left.transform(compressor); + } if (commutativeOperators[self.operator] && self.right.is_constant() && !self.left.is_constant() @@ -6338,17 +6351,28 @@ merge(Compressor.prototype, { case ">=": reverse("<="); break; } } - if (self.operator == "+") { + // x && (y && z) => x && y && z + // x || (y || z) => x || y || z + if (compressor.option("conditionals") + && lazy_op[self.operator] + && self.right instanceof AST_Binary + && self.operator == self.right.operator) { + swap_chain(); + } + if (compressor.option("strings") && self.operator == "+") { + // "foo" + 42 + "" => "foo" + 42 if (self.right instanceof AST_String && self.right.value == "" && self.left.is_string(compressor)) { return self.left.optimize(compressor); } + // "" + ("foo" + 42) => "foo" + 42 if (self.left instanceof AST_String && self.left.value == "" && self.right.is_string(compressor)) { return self.right.optimize(compressor); } + // "" + 42 + "foo" => 42 + "foo" if (self.left instanceof AST_Binary && self.left.operator == "+" && self.left.left instanceof AST_String @@ -6357,6 +6381,14 @@ merge(Compressor.prototype, { self.left = self.left.right; return self.optimize(compressor); } + // "x" + (y + "z") => "x" + y + "z" + // x + ("y" + z) => x + "y" + z + if (self.right instanceof AST_Binary + && self.operator == self.right.operator + && (self.left.is_string(compressor) && self.right.is_string(compressor) + || self.right.left.is_string(compressor) && !self.right.right.has_side_effects(compressor))) { + swap_chain(); + } } if (compressor.option("evaluate")) { var associative = true; @@ -6727,26 +6759,6 @@ merge(Compressor.prototype, { return node.optimize(compressor); } } - // x && (y && z) => x && y && z - // x || (y || z) => x || y || z - // x + ("y" + z) => x + "y" + z - // "x" + (y + "z") => "x" + y + "z" - if (self.right instanceof AST_Binary - && self.right.operator == self.operator - && (lazy_op[self.operator] - || (self.operator == "+" - && (self.right.left.is_string(compressor) - || (self.left.is_string(compressor) - && self.right.right.is_string(compressor)))))) - { - self.left = make_node(AST_Binary, self.left, { - operator : self.operator, - left : self.left, - right : self.right.left - }); - self.right = self.right.right; - return self.transform(compressor); - } return try_evaluate(compressor, self); function align(ref, op) { |