From: Alex Lam S.L Date: Fri, 31 Mar 2017 10:47:44 +0000 (+0800) Subject: combine rules for binary boolean operations (#1744) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=1ddc05725d078ccf73d711e376c3c530cd517cdb;p=UglifyJS.git combine rules for binary boolean operations (#1744) --- diff --git a/lib/compress.js b/lib/compress.js index 55f6d793..a2332a9c 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -3140,42 +3140,7 @@ merge(Compressor.prototype, { } break; } - if (compressor.option("booleans") && compressor.in_boolean_context()) switch (self.operator) { - case "&&": - var ll = self.left.evaluate(compressor); - var rr = self.right.evaluate(compressor); - if (!ll || !rr) { - compressor.warn("Boolean && always false [{file}:{line},{col}]", self.start); - return make_node(AST_Seq, self, { - car: self.left, - cdr: make_node(AST_False, self) - }).optimize(compressor); - } - if (ll !== self.left && ll) { - return self.right.optimize(compressor); - } - if (rr !== self.right && rr) { - return self.left.optimize(compressor); - } - break; - case "||": - var ll = self.left.evaluate(compressor); - var rr = self.right.evaluate(compressor); - if (ll !== self.left && ll || rr !== self.right && rr) { - compressor.warn("Boolean || always true [{file}:{line},{col}]", self.start); - return make_node(AST_Seq, self, { - car: self.left, - cdr: make_node(AST_True, self) - }).optimize(compressor); - } - if (!ll) { - return self.right.optimize(compressor); - } - if (!rr) { - return self.left.optimize(compressor); - } - break; - case "+": + if (compressor.option("booleans") && self.operator == "+" && compressor.in_boolean_context()) { var ll = self.left.evaluate(compressor); var rr = self.right.evaluate(compressor); if (ll && typeof ll == "string") { @@ -3192,7 +3157,6 @@ merge(Compressor.prototype, { cdr: make_node(AST_True, self) }).optimize(compressor); } - break; } if (compressor.option("comparisons") && self.is_boolean()) { if (!(compressor.parent() instanceof AST_Binary) @@ -3233,24 +3197,48 @@ merge(Compressor.prototype, { if (compressor.option("evaluate")) { switch (self.operator) { case "&&": - if (self.left.is_constant()) { - if (self.left.constant_value(compressor)) { - compressor.warn("Condition left of && always true [{file}:{line},{col}]", self.start); - return maintain_this_binding(compressor.parent(), self, self.right); - } else { - compressor.warn("Condition left of && always false [{file}:{line},{col}]", self.start); - return maintain_this_binding(compressor.parent(), self, self.left); + var ll = self.left.evaluate(compressor); + if (!ll) { + compressor.warn("Condition left of && always false [{file}:{line},{col}]", self.start); + return maintain_this_binding(compressor.parent(), self, self.left).optimize(compressor); + } else if (ll !== self.left) { + compressor.warn("Condition left of && always true [{file}:{line},{col}]", self.start); + return maintain_this_binding(compressor.parent(), self, self.right).optimize(compressor); + } + if (compressor.option("booleans") && compressor.in_boolean_context()) { + var rr = self.right.evaluate(compressor); + if (!rr) { + compressor.warn("Boolean && always false [{file}:{line},{col}]", self.start); + return make_node(AST_Seq, self, { + car: self.left, + cdr: make_node(AST_False, self) + }).optimize(compressor); + } else if (rr !== self.right) { + compressor.warn("Dropping side-effect-free && in boolean context [{file}:{line},{col}]", self.start); + return self.left.optimize(compressor); } } break; case "||": - if (self.left.is_constant()) { - if (self.left.constant_value(compressor)) { - compressor.warn("Condition left of || always true [{file}:{line},{col}]", self.start); - return maintain_this_binding(compressor.parent(), self, self.left); - } else { - compressor.warn("Condition left of || always false [{file}:{line},{col}]", self.start); - return maintain_this_binding(compressor.parent(), self, self.right); + var ll = self.left.evaluate(compressor); + if (!ll) { + compressor.warn("Condition left of || always false [{file}:{line},{col}]", self.start); + return maintain_this_binding(compressor.parent(), self, self.right).optimize(compressor); + } else if (ll !== self.left) { + compressor.warn("Condition left of || always true [{file}:{line},{col}]", self.start); + return maintain_this_binding(compressor.parent(), self, self.left).optimize(compressor); + } + if (compressor.option("booleans") && compressor.in_boolean_context()) { + var rr = self.right.evaluate(compressor); + if (!rr) { + compressor.warn("Dropping side-effect-free || in boolean context [{file}:{line},{col}]", self.start); + return self.left.optimize(compressor); + } else if (rr !== self.right) { + compressor.warn("Boolean || always true [{file}:{line},{col}]", self.start); + return make_node(AST_Seq, self, { + car: self.left, + cdr: make_node(AST_True, self) + }).optimize(compressor); } } break; diff --git a/test/compress/issue-1261.js b/test/compress/issue-1261.js index a872c578..343c175b 100644 --- a/test/compress/issue-1261.js +++ b/test/compress/issue-1261.js @@ -154,12 +154,12 @@ should_warn: { "WARN: Boolean || always true [test/compress/issue-1261.js:129,23]", "WARN: Dropping __PURE__ call [test/compress/issue-1261.js:129,23]", "WARN: Condition always true [test/compress/issue-1261.js:129,23]", - "WARN: Boolean || always true [test/compress/issue-1261.js:130,8]", + "WARN: Condition left of || always true [test/compress/issue-1261.js:130,8]", "WARN: Condition always true [test/compress/issue-1261.js:130,8]", "WARN: Boolean && always false [test/compress/issue-1261.js:131,23]", "WARN: Dropping __PURE__ call [test/compress/issue-1261.js:131,23]", "WARN: Condition always false [test/compress/issue-1261.js:131,23]", - "WARN: Boolean && always false [test/compress/issue-1261.js:132,8]", + "WARN: Condition left of && always false [test/compress/issue-1261.js:132,8]", "WARN: Condition always false [test/compress/issue-1261.js:132,8]", "WARN: + in boolean context always true [test/compress/issue-1261.js:133,23]", "WARN: Dropping __PURE__ call [test/compress/issue-1261.js:133,23]",