combine rules for binary boolean operations (#1744)
authorAlex Lam S.L <alexlamsl@gmail.com>
Fri, 31 Mar 2017 10:47:44 +0000 (18:47 +0800)
committerGitHub <noreply@github.com>
Fri, 31 Mar 2017 10:47:44 +0000 (18:47 +0800)
lib/compress.js
test/compress/issue-1261.js

index 55f6d79..a2332a9 100644 (file)
@@ -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;
index a872c57..343c175 100644 (file)
@@ -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]",