fix corner cases in `reduce_vars` (#4674)
authorAlex Lam S.L <alexlamsl@gmail.com>
Mon, 22 Feb 2021 00:21:21 +0000 (00:21 +0000)
committerGitHub <noreply@github.com>
Mon, 22 Feb 2021 00:21:21 +0000 (08:21 +0800)
lib/compress.js
test/compress/arrays.js

index 7577437..0a89de7 100644 (file)
@@ -374,12 +374,20 @@ merge(Compressor.prototype, {
         var lhs = is_lhs(node, parent);
         if (lhs) return lhs;
         if (parent instanceof AST_Array) return is_modified(compressor, tw, parent, parent, level + 1);
+        if (parent instanceof AST_Binary) {
+            if (!lazy_op[parent.operator]) return;
+            return is_modified(compressor, tw, parent, parent, level + 1);
+        }
         if (parent instanceof AST_Call) {
             return !immutable
                 && parent.expression === node
                 && !parent.is_expr_pure(compressor)
                 && (!(value instanceof AST_LambdaExpression) || !(parent instanceof AST_New) && value.contains_this());
         }
+        if (parent instanceof AST_Conditional) {
+            if (parent.condition === node) return;
+            return is_modified(compressor, tw, parent, parent, level + 1);
+        }
         if (parent instanceof AST_ForEnumeration) return parent.init === node;
         if (parent instanceof AST_ObjectKeyVal) {
             if (parent.value !== node) return;
@@ -391,6 +399,10 @@ merge(Compressor.prototype, {
             var prop = read_property(value, parent);
             return (!immutable || recursive) && is_modified(compressor, tw, parent, prop, level + 1);
         }
+        if (parent instanceof AST_Sequence) {
+            if (parent.tail_node() !== node) return;
+            return is_modified(compressor, tw, parent, value, level + 1, immutable, recursive);
+        }
     }
 
     function is_arguments(def) {
index fff7e9b..4767a9a 100644 (file)
@@ -355,3 +355,72 @@ constructor_good: {
     expect_stdout: true
     expect_warnings: []
 }
+
+unsafe_evaluate_modified_binary: {
+    options = {
+        evaluate: true,
+        reduce_vars: true,
+        unsafe: true,
+    }
+    input: {
+        (function(a) {
+            (console && a).push(1);
+            if (a.length)
+                console.log("PASS");
+        })([]);
+    }
+    expect: {
+        (function(a) {
+            (console && a).push(1);
+            if (a.length)
+                console.log("PASS");
+        })([]);
+    }
+    expect_stdout: "PASS"
+}
+
+unsafe_evaluate_modified_conditional: {
+    options = {
+        evaluate: true,
+        reduce_vars: true,
+        unsafe: true,
+    }
+    input: {
+        (function(a) {
+            (console ? a : []).push(1);
+            if (a.length)
+                console.log("PASS");
+        })([]);
+    }
+    expect: {
+        (function(a) {
+            (console ? a : []).push(1);
+            if (a.length)
+                console.log("PASS");
+        })([]);
+    }
+    expect_stdout: "PASS"
+}
+
+unsafe_evaluate_modified_sequence: {
+    options = {
+        evaluate: true,
+        reduce_vars: true,
+        unsafe: true,
+    }
+    input: {
+        (function(a) {
+            (0, a).push(1);
+            if (a.length)
+                console.log("PASS");
+        })([]);
+    }
+    expect: {
+        (function(a) {
+            (0, a).push(1);
+            if (a.length)
+                console.log("PASS");
+        })([]);
+    }
+    expect_stdout: "PASS"
+}