fix corner case in `evaluate` (#3654)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sun, 29 Dec 2019 02:50:57 +0000 (02:50 +0000)
committerGitHub <noreply@github.com>
Sun, 29 Dec 2019 02:50:57 +0000 (02:50 +0000)
fixes #3653

lib/compress.js
test/compress/numbers.js

index 70dafe9..9045a8d 100644 (file)
@@ -6466,13 +6466,6 @@ merge(Compressor.prototype, {
                     }).optimize(compressor);
                 }
                 break;
-              // 0 - n => -n
-              case "-":
-                if (self.left.value == 0) return make_node(AST_UnaryPrefix, self, {
-                    operator: "-",
-                    expression: self.right
-                }).optimize(compressor);
-                break;
               // 1 * n => n
               case "*":
                 if (self.left.value == 1) {
@@ -6483,15 +6476,32 @@ merge(Compressor.prototype, {
                 }
                 break;
             }
-            // n - 0 => n
-            // n / 1 => n
-            if (self.right instanceof AST_Number && !self.left.is_constant() && self.right.value == {
-                "-": 0,
-                "/": 1,
-            }[self.operator]) return self.left.is_number(compressor) ? self.left : make_node(AST_UnaryPrefix, self, {
-                operator: "+",
-                expression: self.left
-            }).optimize(compressor);
+            if (self.right instanceof AST_Number && !self.left.is_constant()) switch (self.operator) {
+              // n + 0 => n
+              case "+":
+                if (self.right.value == 0 && (self.left.is_boolean(compressor) || self.left.is_number(compressor))) {
+                    return self.left;
+                }
+                break;
+              // n - 0 => n
+              case "-":
+                if (self.right.value == 0) {
+                    return self.left.is_number(compressor) ? self.left : make_node(AST_UnaryPrefix, self, {
+                        operator: "+",
+                        expression: self.left
+                    }).optimize(compressor);
+                }
+                break;
+              // n / 1 => n
+              case "/":
+                if (self.right.value == 1) {
+                    return self.left.is_number(compressor) ? self.left : make_node(AST_UnaryPrefix, self, {
+                        operator: "+",
+                        expression: self.left
+                    }).optimize(compressor);
+                }
+                break;
+            }
         }
         if (compressor.option("typeofs")) switch (self.operator) {
           case "&&":
index c432a43..07e93f6 100644 (file)
@@ -997,7 +997,7 @@ identity_1: {
     expect: {
         0 + a;
         a + 0;
-        -a;
+        0 - a;
         +a;
         +a;
         +a;
@@ -1023,7 +1023,7 @@ identity_2: {
     expect: {
         +!a;
         +!a;
-        -!a;
+        0 - !a;
         +!a;
         +!a;
         +!a;
@@ -1049,7 +1049,7 @@ identity_3: {
     expect: {
         --a;
         --a;
-        - --a;
+        - --a;
         --a;
         --a;
         --a;
@@ -1057,3 +1057,42 @@ identity_3: {
         --a;
     }
 }
+
+issue_3653: {
+    options = {
+        evaluate: true,
+    }
+    input: {
+        console.log(0 - (console && 0));
+        console.log(0 + (0 - (console && 0)));
+        console.log(0 - (0 - (console && 0)));
+        console.log(1 * (0 - (console && 0)));
+        console.log(1 / (0 - (console && 0)));
+        console.log((0 - (console && 0)) + 0);
+        console.log((0 - (console && 0)) - 0);
+        console.log((0 - (console && 0)) * 1);
+        console.log((0 - (console && 0)) / 1);
+    }
+    expect: {
+        console.log(0 - (console && 0));
+        console.log(0 - (console && 0));
+        console.log(0 - (0 - (console && 0)));
+        console.log(0 - (console && 0));
+        console.log(1 / (0 - (console && 0)));
+        console.log(0 - (console && 0));
+        console.log(0 - (console && 0));
+        console.log(0 - (console && 0));
+        console.log(0 - (console && 0));
+    }
+    expect_stdout: [
+        "0",
+        "0",
+        "0",
+        "0",
+        "Infinity",
+        "0",
+        "0",
+        "0",
+        "0",
+    ]
+}