fix corner case in `unsafe_math` (#3594)
authorAlex Lam S.L <alexlamsl@gmail.com>
Mon, 18 Nov 2019 05:44:13 +0000 (13:44 +0800)
committerGitHub <noreply@github.com>
Mon, 18 Nov 2019 05:44:13 +0000 (13:44 +0800)
fixes #3593

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

index 45db019..b7a7343 100644 (file)
@@ -6191,38 +6191,12 @@ merge(Compressor.prototype, {
                     && self.left.operator != "%"
                     && PRECEDENCE[self.left.operator] == PRECEDENCE[self.operator]
                     && self.left.is_number(compressor)) {
-                    if (self.left.left instanceof AST_Constant
-                        && (self.operator != "+"
-                            || self.left.left.is_boolean(compressor)
-                            || self.left.left.is_number(compressor))) {
-                        self = make_node(AST_Binary, self, {
-                            operator: self.left.operator,
-                            left: make_node(AST_Binary, self.left, {
-                                operator: self.operator,
-                                left: self.left.left,
-                                right: self.right,
-                                start: self.left.left.start,
-                                end: self.right.end
-                            }),
-                            right: self.left.right
-                        });
+                    if (self.left.left instanceof AST_Constant) {
+                        var lhs = make_binary(self.left, self.operator, self.left.left, self.right, self.left.left.start, self.right.end);
+                        self = make_binary(self, self.left.operator, lhs, self.left.right);
                     } else if (self.left.right instanceof AST_Constant) {
-                        var op = align(self.left.operator, self.operator);
-                        if (op != "+"
-                            || self.left.right.is_boolean(compressor)
-                            || self.left.right.is_number(compressor)) {
-                            self = make_node(AST_Binary, self, {
-                                operator: self.left.operator,
-                                left: self.left.left,
-                                right: make_node(AST_Binary, self.left, {
-                                    operator: op,
-                                    left: self.left.right,
-                                    right: self.right,
-                                    start: self.left.right.start,
-                                    end: self.right.end
-                                })
-                            });
-                        }
+                        var rhs = make_binary(self.left, align(self.left.operator, self.operator), self.left.right, self.right, self.left.right.start, self.right.end);
+                        self = make_binary(self, self.left.operator, self.left.left, rhs);
                     }
                 }
                 break;
@@ -6304,6 +6278,30 @@ merge(Compressor.prototype, {
             }
         }
 
+        function make_binary(orig, op, left, right, start, end) {
+            if (op == "+") {
+                if (!left.is_boolean(compressor) && !left.is_number(compressor)) {
+                    left = make_node(AST_UnaryPrefix, left, {
+                        operator: "+",
+                        expression: left
+                    });
+                }
+                if (!right.is_boolean(compressor) && !right.is_number(compressor)) {
+                    right = make_node(AST_UnaryPrefix, right, {
+                        operator: "+",
+                        expression: right
+                    });
+                }
+            }
+            return make_node(AST_Binary, orig, {
+                operator: op,
+                left: left,
+                right: right,
+                start: start,
+                end: end
+            });
+        }
+
         function fuzzy_eval(node) {
             if (node.truthy) return true;
             if (node.falsy) return false;
index ee20fc1..1203412 100644 (file)
@@ -870,7 +870,7 @@ issue_3547_3: {
             a + "21",
             a + "2" - 1,
             a - 1,
-            a - "2" - 1,
+            a - 3,
         ].forEach(function(n) {
             console.log(typeof n, n);
         });
@@ -904,7 +904,7 @@ issue_3547_4: {
         [
             "3" + a + 1,
             "3" + a - 1,
-            "3" - a + 1,
+            4 - a,
             2 - a,
         ].forEach(function(n) {
             console.log(typeof n, n);
@@ -931,3 +931,17 @@ unsafe_math_rounding: {
     }
     expect_stdout: "false"
 }
+
+issue_3593: {
+    options = {
+        evaluate: true,
+        unsafe_math: true,
+    }
+    input: {
+        console.log((0 === this) - 1 - "1");
+    }
+    expect: {
+        console.log((0 === this) - 2);
+    }
+    expect_stdout: "-2"
+}