improve compression of `if` conditions (#2544)
authorAlex Lam S.L <alexlamsl@gmail.com>
Thu, 30 Nov 2017 22:18:31 +0000 (06:18 +0800)
committerGitHub <noreply@github.com>
Thu, 30 Nov 2017 22:18:31 +0000 (06:18 +0800)
lib/compress.js
test/compress/conditionals.js
test/compress/dead-code.js
test/compress/functions.js
test/compress/global_defs.js
test/compress/transform.js

index e6215f6..395c4ed 100644 (file)
@@ -3147,28 +3147,34 @@ merge(Compressor.prototype, {
         // “has no side effects”; also it doesn't work for cases like
         // `x && true`, though it probably should.
         var cond = self.condition.evaluate(compressor);
-        if (cond !== self.condition) {
-            if (cond) {
-                compressor.warn("Condition always true [{file}:{line},{col}]", self.condition.start);
-                if (compressor.option("dead_code")) {
-                    var a = [];
-                    if (self.alternative) {
-                        extract_declarations_from_unreachable_code(compressor, self.alternative, a);
-                    }
-                    a.push(self.body);
-                    return make_node(AST_BlockStatement, self, { body: a }).optimize(compressor);
-                }
-            } else {
+        if (!compressor.option("dead_code") && !(cond instanceof AST_Node)) {
+            var orig = self.condition;
+            self.condition = make_node_from_constant(cond, orig);
+            self.condition = best_of_expression(self.condition.transform(compressor), orig);
+        }
+        if (compressor.option("dead_code")) {
+            if (cond instanceof AST_Node) cond = self.condition.tail_node().evaluate(compressor);
+            if (!cond) {
                 compressor.warn("Condition always false [{file}:{line},{col}]", self.condition.start);
-                if (compressor.option("dead_code")) {
-                    var a = [];
-                    extract_declarations_from_unreachable_code(compressor, self.body, a);
-                    if (self.alternative) a.push(self.alternative);
-                    return make_node(AST_BlockStatement, self, { body: a }).optimize(compressor);
+                var body = [];
+                extract_declarations_from_unreachable_code(compressor, self.body, body);
+                body.push(make_node(AST_SimpleStatement, self.condition, {
+                    body: self.condition
+                }));
+                if (self.alternative) body.push(self.alternative);
+                return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor);
+            } else if (!(cond instanceof AST_Node)) {
+                compressor.warn("Condition always true [{file}:{line},{col}]", self.condition.start);
+                var body = [];
+                if (self.alternative) {
+                    extract_declarations_from_unreachable_code(compressor, self.alternative, body);
                 }
+                body.push(make_node(AST_SimpleStatement, self.condition, {
+                    body: self.condition
+                }));
+                body.push(self.body);
+                return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor);
             }
-            cond = make_node_from_constant(cond, self.condition).transform(compressor);
-            self.condition = best_of_expression(cond, self.condition);
         }
         var negated = self.condition.negate(compressor);
         var self_condition_length = self.condition.print_to_string().length;
index 7a6688b..9cb27fa 100644 (file)
@@ -1015,3 +1015,32 @@ delete_conditional_2: {
     }
     expect_stdout: true
 }
+
+issue_2535: {
+    options = {
+        booleans: true,
+        conditionals: true,
+        evaluate: true,
+        passes: 2,
+        side_effects: true,
+    }
+    input: {
+        if (true || x()) y();
+        if (true && x()) y();
+        if (x() || true) y();
+        if (x() && true) y();
+        if (false || x()) y();
+        if (false && x()) y();
+        if (x() || false) y();
+        if (x() && false) y();
+    }
+    expect: {
+        y();
+        x() && y();
+        (x(), 0) || y();
+        x() && y();
+        x() && y();
+        x() && y();
+        (x(), 1) || y();
+    }
+}
index e0c3039..9baf998 100644 (file)
@@ -178,6 +178,8 @@ try_catch_finally: {
         conditionals: true,
         dead_code: true,
         evaluate: true,
+        passes: 2,
+        side_effects: true,
     }
     input: {
         var a = 1;
index 3ecb4bc..7a336bb 100644 (file)
@@ -87,6 +87,7 @@ issue_485_crashing_1530: {
         dead_code: true,
         evaluate: true,
         inline: true,
+        side_effects: true,
     }
     input: {
         (function(a) {
@@ -94,9 +95,7 @@ issue_485_crashing_1530: {
             var b = 42;
         })(this);
     }
-    expect: {
-        this, void 0;
-    }
+    expect: {}
 }
 
 issue_1841_1: {
index bd791e2..7b72819 100644 (file)
@@ -184,6 +184,7 @@ issue_2167: {
         global_defs: {
             "@isDevMode": "function(){}",
         },
+        passes: 2,
         side_effects: true,
     }
     input: {
index 48aa605..1e21da5 100644 (file)
@@ -68,6 +68,7 @@ label_if_break: {
         conditionals: true,
         dead_code: true,
         evaluate: true,
+        side_effects: true,
     }
     input: {
         L: if (true) {