fix corner case in `conditionals` (#3577)
authorAlex Lam S.L <alexlamsl@gmail.com>
Fri, 8 Nov 2019 16:53:15 +0000 (00:53 +0800)
committerGitHub <noreply@github.com>
Fri, 8 Nov 2019 16:53:15 +0000 (00:53 +0800)
fixes #3576

lib/compress.js
test/compress/conditionals.js

index 43ee112..26d1729 100644 (file)
@@ -6673,7 +6673,7 @@ merge(Compressor.prototype, {
                 && alt_tail instanceof AST_Assign
                 && seq_tail.operator == alt_tail.operator
                 && seq_tail.left.equivalent_to(alt_tail.left)
-                && (is_eq && !seq_tail.left.has_side_effects(compressor)
+                && (is_eq && seq_tail.left instanceof AST_SymbolRef
                     || !condition.has_side_effects(compressor)
                         && can_shift_lhs_of_tail(consequent)
                         && can_shift_lhs_of_tail(alternative))) {
@@ -6842,16 +6842,9 @@ merge(Compressor.prototype, {
         }
 
         function can_shift_lhs_of_tail(node) {
-            if (node === node.tail_node()) return true;
-            var exprs = node.expressions;
-            for (var i = exprs.length - 1; --i >= 0;) {
-                var expr = exprs[i];
-                if (!(expr instanceof AST_Assign) && expr.has_side_effects(compressor)
-                    || expr.operator != "="
-                    || expr.left.has_side_effects(compressor)
-                    || expr.right.has_side_effects(compressor)) return false;
-            }
-            return true;
+            return node === node.tail_node() || all(node.expressions.slice(0, -1), function(expr) {
+                return !expr.has_side_effects(compressor);
+            });
         }
 
         function pop_lhs(node) {
index 27536b9..3e7a092 100644 (file)
@@ -1489,3 +1489,29 @@ angularjs_chain: {
         }
     }
 }
+
+issue_3576: {
+    options = {
+        conditionals: true,
+        evaluate: true,
+        pure_getters: "strict",
+        reduce_vars: true,
+    }
+    input: {
+        var c = "FAIL";
+        (function(a) {
+            (a = -1) ? (a && (a.a = 0)) : (a && (a.a = 0));
+            a && a[c = "PASS"]++;
+        })();
+        console.log(c);
+    }
+    expect: {
+        var c = "FAIL";
+        (function(a) {
+            a = -1, a, a.a = 0;
+            a, a[c = "PASS"]++;
+        })();
+        console.log(c);
+    }
+    expect_stdout: "PASS"
+}