simplify comparisons with `undefined` & `null` (#2862)
authorAlex Lam S.L <alexlamsl@gmail.com>
Thu, 1 Feb 2018 08:50:54 +0000 (16:50 +0800)
committerGitHub <noreply@github.com>
Thu, 1 Feb 2018 08:50:54 +0000 (16:50 +0800)
fixes #2857

lib/compress.js
test/compress/comparing.js

index b4d13ec..a88ea2c 100644 (file)
@@ -4788,6 +4788,34 @@ merge(Compressor.prototype, {
                 return make_node(self.operator[0] == "=" ? AST_True : AST_False, self);
             }
             break;
+          case "&&":
+          case "||":
+            var lhs = self.left;
+            if (lhs.operator == self.operator) {
+                lhs = lhs.right;
+            }
+            if (lhs instanceof AST_Binary
+                && lhs.operator == (self.operator == "&&" ? "!==" : "===")
+                && self.right instanceof AST_Binary
+                && lhs.operator == self.right.operator
+                && (is_undefined(lhs.left, compressor) && self.right.left instanceof AST_Null
+                    || lhs.left instanceof AST_Null && is_undefined(self.right.left, compressor))
+                && lhs.right.equivalent_to(self.right.right)) {
+                var combined = make_node(AST_Binary, self, {
+                    operator: lhs.operator.slice(0, -1),
+                    left: make_node(AST_Null, self),
+                    right: lhs.right
+                });
+                if (lhs !== self.left) {
+                    combined = make_node(AST_Binary, self, {
+                        operator: self.operator,
+                        left: self.left.left,
+                        right: combined
+                    });
+                }
+                return combined;
+            }
+            break;
         }
         if (self.operator == "+" && compressor.in_boolean_context()) {
             var ll = self.left.evaluate(compressor);
index e374b58..d581d08 100644 (file)
@@ -112,3 +112,133 @@ self_comparison_2: {
     }
     expect_stdout: "false true"
 }
+
+issue_2857_1: {
+    options = {
+        comparisons: true,
+    }
+    input: {
+        a === undefined || a === null;
+        a === undefined || a !== null;
+        a !== undefined || a === null;
+        a !== undefined || a !== null;
+        a === undefined && a === null;
+        a === undefined && a !== null;
+        a !== undefined && a === null;
+        a !== undefined && a !== null;
+    }
+    expect: {
+        null == a;
+        void 0 === a || null !== a;
+        void 0 !== a || null === a;
+        void 0 !== a || null !== a;
+        void 0 === a && null === a;
+        void 0 === a && null !== a;
+        void 0 !== a && null === a;
+        null != a;
+    }
+}
+
+issue_2857_2: {
+    options = {
+        comparisons: true,
+    }
+    input: {
+        a === undefined || a === null || p;
+        a === undefined || a !== null || p;
+        a !== undefined || a === null || p;
+        a !== undefined || a !== null || p;
+        a === undefined && a === null || p;
+        a === undefined && a !== null || p;
+        a !== undefined && a === null || p;
+        a !== undefined && a !== null || p;
+    }
+    expect: {
+        null == a || p;
+        void 0 === a || null !== a || p;
+        void 0 !== a || null === a || p;
+        void 0 !== a || null !== a || p;
+        void 0 === a && null === a || p;
+        void 0 === a && null !== a || p;
+        void 0 !== a && null === a || p;
+        null != a || p;
+    }
+}
+
+issue_2857_3: {
+    options = {
+        comparisons: true,
+    }
+    input: {
+        a === undefined || a === null && p;
+        a === undefined || a !== null && p;
+        a !== undefined || a === null && p;
+        a !== undefined || a !== null && p;
+        a === undefined && a === null && p;
+        a === undefined && a !== null && p;
+        a !== undefined && a === null && p;
+        a !== undefined && a !== null && p;
+    }
+    expect: {
+        void 0 === a || null === a && p;
+        void 0 === a || null !== a && p;
+        void 0 !== a || null === a && p;
+        void 0 !== a || null !== a && p;
+        void 0 === a && null === a && p;
+        void 0 === a && null !== a && p;
+        void 0 !== a && null === a && p;
+        null != a && p;
+    }
+}
+
+issue_2857_4: {
+    options = {
+        comparisons: true,
+    }
+    input: {
+        p || a === undefined || a === null;
+        p || a === undefined || a !== null;
+        p || a !== undefined || a === null;
+        p || a !== undefined || a !== null;
+        p || a === undefined && a === null;
+        p || a === undefined && a !== null;
+        p || a !== undefined && a === null;
+        p || a !== undefined && a !== null;
+    }
+    expect: {
+        p || null == a;
+        p || void 0 === a || null !== a;
+        p || void 0 !== a || null === a;
+        p || void 0 !== a || null !== a;
+        p || void 0 === a && null === a;
+        p || void 0 === a && null !== a;
+        p || void 0 !== a && null === a;
+        p || null != a;
+    }
+}
+
+issue_2857_5: {
+    options = {
+        comparisons: true,
+    }
+    input: {
+        p && a === undefined || a === null;
+        p && a === undefined || a !== null;
+        p && a !== undefined || a === null;
+        p && a !== undefined || a !== null;
+        p && a === undefined && a === null;
+        p && a === undefined && a !== null;
+        p && a !== undefined && a === null;
+        p && a !== undefined && a !== null;
+    }
+    expect: {
+        p && void 0 === a || null === a;
+        p && void 0 === a || null !== a;
+        p && void 0 !== a || null === a;
+        p && void 0 !== a || null !== a;
+        p && void 0 === a && null === a;
+        p && void 0 === a && null !== a;
+        p && void 0 !== a && null === a;
+        p && null != a;
+    }
+}