enhance `unsafe_math` (#3603)
authorAlex Lam S.L <alexlamsl@gmail.com>
Mon, 25 Nov 2019 13:14:13 +0000 (21:14 +0800)
committerGitHub <noreply@github.com>
Mon, 25 Nov 2019 13:14:13 +0000 (21:14 +0800)
lib/compress.js
test/compress/numbers.js

index 43c32a7..c195c42 100644 (file)
@@ -5811,14 +5811,15 @@ merge(Compressor.prototype, {
                 self.right = tmp;
             }
         }
-        if (commutativeOperators[self.operator] && self.right.is_constant() && !self.left.is_constant()) {
+        if (commutativeOperators[self.operator]
+            && self.right.is_constant()
+            && !self.left.is_constant()
+            && !(self.left instanceof AST_Binary
+                && PRECEDENCE[self.left.operator] >= PRECEDENCE[self.operator])) {
             // if right is a constant, whatever side effects the
             // left side might have could not influence the
             // result.  hence, force switch.
-            if (!(self.left instanceof AST_Binary
-                    && PRECEDENCE[self.left.operator] >= PRECEDENCE[self.operator])) {
-                reverse();
-            }
+            reverse();
         }
         self = self.lift_sequences(compressor);
         if (compressor.option("assignments") && lazy_op[self.operator]) {
@@ -6129,6 +6130,26 @@ merge(Compressor.prototype, {
                     });
                     break;
                 }
+                // (a + b) + 3 => 3 + (a + b)
+                if (compressor.option("unsafe_math")
+                    && self.left instanceof AST_Binary
+                    && PRECEDENCE[self.left.operator] == PRECEDENCE[self.operator]
+                    && self.right.is_constant()
+                    && (self.right.is_boolean(compressor) || self.right.is_number(compressor))
+                    && self.left.is_number(compressor)
+                    && !self.left.right.is_constant()
+                    && (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, {
+                            operator: self.operator,
+                            left: self.right,
+                            right: self.left.left
+                        }),
+                        right: self.left.right
+                    });
+                    break;
+                }
               case "-":
                 // a - -b => a + b
                 if (self.right instanceof AST_UnaryPrefix
index 1203412..673ce23 100644 (file)
@@ -945,3 +945,37 @@ issue_3593: {
     }
     expect_stdout: "-2"
 }
+
+unsafe_math_swap_constant: {
+    options = {
+        evaluate: true,
+        unsafe_math: true,
+    }
+    input: {
+        var a = 1, b = 2;
+        console.log(
+            a++ + b-- + 3,
+            a++ + b + 3,
+            a + b-- + 3,
+            a + b + 3,
+            a++ - b-- + 3,
+            a++ - b + 3,
+            a - b-- + 3,
+            a - b + 3
+        );
+    }
+    expect: {
+        var a = 1, b = 2;
+        console.log(
+            3 + a++ + b--,
+            a++ + b + 3,
+            a + b-- + 3,
+            a + b + 3,
+            3 + a++ - b--,
+            3 + a++ - b,
+            a - b-- + 3,
+            a - b + 3
+        );
+    }
+    expect_stdout: "6 6 7 6 6 8 9 10"
+}