enhance `collapse_vars` (#4864)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sat, 24 Apr 2021 04:45:18 +0000 (05:45 +0100)
committerGitHub <noreply@github.com>
Sat, 24 Apr 2021 04:45:18 +0000 (12:45 +0800)
lib/compress.js
test/compress/collapse_vars.js

index f0e7ab8..6f102e7 100644 (file)
@@ -1856,6 +1856,7 @@ merge(Compressor.prototype, {
                       case 0:
                         hit = true;
                         if (assign_used) return node;
+                        if (node !== candidate) return node;
                         if (node instanceof AST_VarDef) return node;
                         def.replaced++;
                         var parent = multi_replacer.parent();
@@ -1957,7 +1958,9 @@ merge(Compressor.prototype, {
                         for (var i = stat_index; !abort && i < statements.length; i++) {
                             if (!statements[i].transform(multi_replacer)) statements.splice(i--, 1);
                         }
-                        if (candidate instanceof AST_VarDef) {
+                        if (candidate !== hit_stack[hit_stack.length - 1]) {
+                            replaced = false;
+                        } else if (candidate instanceof AST_VarDef) {
                             replaced = !compressor.exposed(def) && def.references.length == def.replaced;
                         }
                         value_def.single_use = false;
@@ -2546,15 +2549,23 @@ merge(Compressor.prototype, {
                 }
             }
 
-            function mangleable_var(value) {
+            function mangleable_var(rhs) {
                 if (force_single) {
                     force_single = false;
                     return;
                 }
+                var value = rhs instanceof AST_Assign && rhs.operator == "=" ? rhs.left : rhs;
                 if (!(value instanceof AST_SymbolRef)) return;
                 var def = value.definition();
                 if (def.undeclared) return;
                 if (is_arguments(def)) return;
+                if (value !== rhs) {
+                    if (value.is_immutable()) return;
+                    var referenced = def.references.length - def.replaced;
+                    if (referenced < 2) return;
+                    candidate = candidate.clone();
+                    candidate[candidate instanceof AST_Assign ? "right" : "value"] = value;
+                }
                 return value_def = def;
             }
 
index fcc4739..451681b 100644 (file)
@@ -8064,6 +8064,67 @@ mangleable_var: {
     expect_stdout: "PASS"
 }
 
+mangleable_assignment_1: {
+    options = {
+        collapse_vars: true,
+        unused: true,
+    }
+    input: {
+        var o = {
+            p: function() {
+                return 6;
+            },
+        };
+        (function() {
+            var a, b = a = o.p();
+            console.log(a * (b / a + b));
+        })();
+    }
+    expect: {
+        var o = {
+            p: function() {
+                return 6;
+            },
+        };
+        (function() {
+            var a;
+            a = o.p();
+            console.log(a * (a / a + a));
+        })();
+    }
+    expect_stdout: "42"
+}
+
+mangleable_assignment_2: {
+    options = {
+        collapse_vars: true,
+        unused: true,
+    }
+    input: {
+        var o = {
+            p: function() {
+                return 6;
+            },
+        };
+        (function(a, b) {
+            b = a = o.p();
+            console.log(a * (b / a + b));
+        })();
+    }
+    expect: {
+        var o = {
+            p: function() {
+                return 6;
+            },
+        };
+        (function(a, b) {
+            a = o.p();
+            console.log(a * (a / a + a));
+        })();
+    }
+    expect_stdout: "42"
+}
+
 issue_3884_1: {
     options = {
         collapse_vars: true,