enhance `evaluate` (#3660)
authorAlex Lam S.L <alexlamsl@gmail.com>
Tue, 31 Dec 2019 03:51:21 +0000 (11:51 +0800)
committerGitHub <noreply@github.com>
Tue, 31 Dec 2019 03:51:21 +0000 (11:51 +0800)
lib/compress.js

index 76ad399..3f6bc89 100644 (file)
@@ -2023,7 +2023,7 @@ merge(Compressor.prototype, {
                     var value = stat.body.value;
                     //---
                     // pretty silly case, but:
-                    // if (foo()) return; return; ==> foo(); return;
+                    // if (foo()) return; return; => foo(); return;
                     if (!value && !stat.alternative
                         && (in_lambda && !next || next instanceof AST_Return && !next.value)) {
                         CHANGED = true;
@@ -2033,7 +2033,7 @@ merge(Compressor.prototype, {
                         continue;
                     }
                     //---
-                    // if (foo()) return x; return y; ==> return foo() ? x : y;
+                    // if (foo()) return x; return y; => return foo() ? x : y;
                     if (value && !stat.alternative && next instanceof AST_Return && next.value) {
                         CHANGED = true;
                         stat = stat.clone();
@@ -2043,7 +2043,7 @@ merge(Compressor.prototype, {
                         continue;
                     }
                     //---
-                    // if (foo()) return x; [ return ; ] ==> return foo() ? x : undefined;
+                    // if (foo()) return x; [ return ; ] => return foo() ? x : undefined;
                     if (value && !stat.alternative
                         && (!next && in_lambda && multiple_if_returns
                             || next instanceof AST_Return)) {
@@ -2057,7 +2057,7 @@ merge(Compressor.prototype, {
                         continue;
                     }
                     //---
-                    // if (a) return b; if (c) return d; e; ==> return a ? b : c ? d : void e;
+                    // if (a) return b; if (c) return d; e; => return a ? b : c ? d : void e;
                     //
                     // if sequences is not enabled, this can lead to an endless loop (issue #866).
                     // however, with sequences on this helps producing slightly better output for
@@ -6025,7 +6025,7 @@ merge(Compressor.prototype, {
             } else if (compressor.in_boolean_context()) switch (self.operator) {
               case "!":
                 if (e instanceof AST_UnaryPrefix && e.operator == "!") {
-                    // !!foo ==> foo, if we're in boolean context
+                    // !!foo => foo, if we're in boolean context
                     return e.expression;
                 }
                 if (e instanceof AST_Binary) {
@@ -6317,9 +6317,9 @@ merge(Compressor.prototype, {
                         return self.left.optimize(compressor);
                     }
                 }
-                // x || false && y ---> x ? y : false
+                // (x || false) && y => x ? y : false
                 if (self.left.operator == "||") {
-                    var lr = self.left.right.evaluate(compressor);
+                    var lr = self.left.right.tail_node().evaluate(compressor);
                     if (!lr) return make_node(AST_Conditional, self, {
                         condition: self.left.left,
                         consequent: self.right,
@@ -6351,8 +6351,9 @@ merge(Compressor.prototype, {
                         ]).optimize(compressor);
                     } else self.truthy = true;
                 }
+                // x && true || y => x ? true : y
                 if (self.left.operator == "&&") {
-                    var lr = self.left.right.evaluate(compressor);
+                    var lr = self.left.right.is_truthy() || self.left.right.tail_node().evaluate(compressor);
                     if (lr && !(lr instanceof AST_Node)) return make_node(AST_Conditional, self, {
                         condition: self.left.left,
                         consequent: self.left.right,
@@ -6650,10 +6651,10 @@ merge(Compressor.prototype, {
                 return node.optimize(compressor);
             }
         }
-        // x && (y && z)  ==>  x && y && z
-        // x || (y || z)  ==>  x || y || z
-        // x + ("y" + z)  ==>  x + "y" + z
-        // "x" + (y + "z")==>  "x" + y + "z"
+        // x && (y && z) => x && y && z
+        // x || (y || z) => x || y || z
+        // x + ("y" + z) => x + "y" + z
+        // "x" + (y + "z") => "x" + y + "z"
         if (self.right instanceof AST_Binary
             && self.right.operator == self.operator
             && (lazy_op[self.operator]
@@ -7055,7 +7056,7 @@ merge(Compressor.prototype, {
             if (self.right.left instanceof AST_SymbolRef
                 && self.right.left.name == self.left.name
                 && ASSIGN_OPS[self.right.operator]) {
-                // x = x - 2  --->  x -= 2
+                // x = x - 2 => x -= 2
                 self.operator = self.right.operator + "=";
                 self.right = self.right.right;
             }
@@ -7063,7 +7064,7 @@ merge(Compressor.prototype, {
                 && self.right.right.name == self.left.name
                 && ASSIGN_OPS_COMMUTATIVE[self.right.operator]
                 && !self.right.left.has_side_effects(compressor)) {
-                // x = 2 & x  --->  x &= 2
+                // x = 2 & x => x &= 2
                 self.operator = self.right.operator + "=";
                 self.right = self.right.left;
             }
@@ -7132,7 +7133,7 @@ merge(Compressor.prototype, {
         var condition = self.condition;
         var consequent = self.consequent;
         var alternative = self.alternative;
-        // x?x:y --> x||y
+        // x ? x : y => x || y
         if (condition instanceof AST_SymbolRef
             && consequent instanceof AST_SymbolRef
             && condition.definition() === consequent.definition()) {
@@ -7169,7 +7170,7 @@ merge(Compressor.prototype, {
                 });
             }
         }
-        // x ? y : y --> x, y
+        // x ? y : y => x, y
         if (consequent.equivalent_to(alternative)) return make_sequence(self, [
             condition,
             consequent
@@ -7178,7 +7179,7 @@ merge(Compressor.prototype, {
             && alternative.TYPE === consequent.TYPE
             && consequent.args.length == alternative.args.length) {
             var arg_index = arg_diff();
-            // x ? y(a) : z(a) --> (x ? y : z)(a)
+            // x ? y(a) : z(a) => (x ? y : z)(a)
             if (arg_index == -1
                 && !(consequent.expression instanceof AST_PropAccess)
                 && !(alternative.expression instanceof AST_PropAccess)) {
@@ -7190,7 +7191,7 @@ merge(Compressor.prototype, {
                 });
                 return node;
             }
-            // x ? y(a) : y(b) --> y(x ? a : b)
+            // x ? y(a) : y(b) => y(x ? a : b)
             if (arg_index >= 0
                 && consequent.expression.equivalent_to(alternative.expression)
                 && !condition.has_side_effects(compressor)
@@ -7204,7 +7205,7 @@ merge(Compressor.prototype, {
                 return node;
             }
         }
-        // x ? (y ? a : b) : b --> x && y ? a : b
+        // x ? (y ? a : b) : b => x && y ? a : b
         if (consequent instanceof AST_Conditional
             && consequent.alternative.equivalent_to(alternative)) {
             return make_node(AST_Conditional, self, {
@@ -7217,7 +7218,7 @@ merge(Compressor.prototype, {
                 alternative: alternative
             });
         }
-        // x ? a : (y ? a : b)--> x || y ? a : b
+        // x ? a : (y ? a : b) => x || y ? a : b
         if (alternative instanceof AST_Conditional
             && consequent.equivalent_to(alternative.consequent)) {
             return make_node(AST_Conditional, self, {
@@ -7230,7 +7231,7 @@ merge(Compressor.prototype, {
                 alternative: alternative.alternative
             });
         }
-        // x ? (y, w) : (z, w) --> x ? y : z, w
+        // x ? (y, w) : (z, w) => x ? y : z, w
         if ((consequent instanceof AST_Sequence || alternative instanceof AST_Sequence)
             && consequent.tail_node().equivalent_to(alternative.tail_node())) {
             return make_sequence(self, [
@@ -7242,7 +7243,7 @@ merge(Compressor.prototype, {
                 consequent.tail_node()
             ]).optimize(compressor);
         }
-        // x ? y || z : z --> x && y || z
+        // x ? y || z : z => x && y || z
         if (consequent instanceof AST_Binary
             && consequent.operator == "||"
             && consequent.right.equivalent_to(alternative)) {
@@ -7259,10 +7260,10 @@ merge(Compressor.prototype, {
         var in_bool = compressor.option("booleans") && compressor.in_boolean_context();
         if (is_true(consequent)) {
             if (is_false(alternative)) {
-                // c ? true : false ---> !!c
+                // c ? true : false => !!c
                 return booleanize(condition);
             }
-            // c ? true : x ---> !!c || x
+            // c ? true : x => !!c || x
             return make_node(AST_Binary, self, {
                 operator: "||",
                 left: booleanize(condition),
@@ -7271,10 +7272,10 @@ merge(Compressor.prototype, {
         }
         if (is_false(consequent)) {
             if (is_true(alternative)) {
-                // c ? false : true ---> !c
+                // c ? false : true => !c
                 return booleanize(condition.negate(compressor));
             }
-            // c ? false : x ---> !c && x
+            // c ? false : x => !c && x
             return make_node(AST_Binary, self, {
                 operator: "&&",
                 left: booleanize(condition.negate(compressor)),
@@ -7282,7 +7283,7 @@ merge(Compressor.prototype, {
             });
         }
         if (is_true(alternative)) {
-            // c ? x : true ---> !c || x
+            // c ? x : true => !c || x
             return make_node(AST_Binary, self, {
                 operator: "||",
                 left: booleanize(condition.negate(compressor)),
@@ -7290,7 +7291,7 @@ merge(Compressor.prototype, {
             });
         }
         if (is_false(alternative)) {
-            // c ? x : false ---> !!c && x
+            // c ? x : false => !!c && x
             return make_node(AST_Binary, self, {
                 operator: "&&",
                 left: booleanize(condition),