fix corner case in `conditionals` (#3809)
authorAlex Lam S.L <alexlamsl@gmail.com>
Tue, 21 Apr 2020 22:30:08 +0000 (23:30 +0100)
committerGitHub <noreply@github.com>
Tue, 21 Apr 2020 22:30:08 +0000 (06:30 +0800)
fixes #3808

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

index ef032b3..d055132 100644 (file)
@@ -4933,9 +4933,21 @@ merge(Compressor.prototype, {
         });
         def(AST_Sequence, function(compressor, first_in_statement) {
             var expressions = trim(this.expressions, compressor, first_in_statement);
-            if (expressions === this.expressions) return this;
             if (!expressions) return null;
-            return make_sequence(this, expressions);
+            var end = expressions.length - 1;
+            var assign, cond, lhs;
+            if (compressor.option("conditionals")
+                && end > 0
+                && (assign = expressions[end - 1]) instanceof AST_Assign
+                && assign.operator == "="
+                && (lhs = assign.left) instanceof AST_SymbolRef
+                && (cond = to_conditional_assignment(compressor, lhs.definition(), assign.right, expressions[end]))) {
+                assign = assign.clone();
+                assign.right = cond;
+                expressions = expressions.slice(0, -2);
+                expressions.push(assign);
+            }
+            return expressions === this.expressions ? this : make_sequence(this, expressions);
         });
         def(AST_Sub, function(compressor, first_in_statement) {
             if (this.expression.may_throw_on_access(compressor)) return this;
@@ -6390,16 +6402,16 @@ merge(Compressor.prototype, {
 
         function merge_conditional_assignments() {
             if (!compressor.option("conditionals")) return;
-            for (var i = 0; i < end; i++) {
-                var assign = expressions[i];
+            for (var i = 1; i < end; i++) {
+                var assign = expressions[i - 1];
                 if (!(assign instanceof AST_Assign)) continue;
                 if (assign.operator != "=") continue;
                 if (!(assign.left instanceof AST_SymbolRef)) continue;
                 var def = assign.left.definition();
-                var cond = to_conditional_assignment(compressor, def, assign.right, expressions[i + 1]);
+                var cond = to_conditional_assignment(compressor, def, assign.right, expressions[i]);
                 if (!cond) continue;
                 assign.right = cond;
-                expressions.splice(i + 1, 1);
+                expressions.splice(i, 1);
                 end--;
             }
         }
index 26f6b73..ab9c410 100644 (file)
@@ -1759,3 +1759,37 @@ conditional_assignments_3: {
     }
     expect_stdout: "PASS"
 }
+
+issue_3808_1: {
+    options = {
+        conditionals: true,
+        side_effects: true,
+    }
+    input: {
+        var a;
+        a = "PASS", [] + "" && (a = "FAIL");
+        console.log(a);
+    }
+    expect: {
+        var a;
+        a = [] + "" ? "FAIL" : "PASS";
+        console.log(a);
+    }
+    expect_stdout: "PASS"
+}
+
+issue_3808_2: {
+    options = {
+        conditionals: true,
+        side_effects: true,
+    }
+    input: {
+        var a;
+        console.log((a = "PASS", [] + "" && (a = "FAIL")), a);
+    }
+    expect: {
+        var a;
+        console.log((a = "PASS", [] + "" && (a = "FAIL")), a);
+    }
+    expect_stdout: " PASS"
+}