enhance `collapse_vars` (#3793)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sat, 18 Apr 2020 02:06:20 +0000 (03:06 +0100)
committerGitHub <noreply@github.com>
Sat, 18 Apr 2020 02:06:20 +0000 (10:06 +0800)
lib/compress.js
test/compress/collapse_vars.js

index 70ac9b8..d07c241 100644 (file)
@@ -1307,12 +1307,10 @@ merge(Compressor.prototype, {
                         if (candidate instanceof AST_Assign) referenced--;
                         if (replaced && referenced == replaced) {
                             abort = false;
-                        } else if (candidate instanceof AST_Assign) {
+                        } else {
                             candidates.push(hit_stack);
                             force_single = true;
                             continue;
-                        } else {
-                            replaced = false;
                         }
                         if (replaced) {
                             hit_index = 0;
@@ -1320,6 +1318,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) {
+                                replaced = !compressor.exposed(def) && def.references.length == def.replaced;
+                            }
                             value_def.single_use = false;
                         }
                     }
@@ -1738,8 +1739,11 @@ merge(Compressor.prototype, {
                     if (!member(expr.name, def.orig)) return;
                     var referenced = def.references.length - def.replaced;
                     var declared = def.orig.length - def.eliminated;
-                    if (declared > 1 && !(expr.name instanceof AST_SymbolFunarg)
-                        || (referenced > 1 ? mangleable_var(expr.value) : !compressor.exposed(def))) {
+                    if (declared > 1 && !(expr.name instanceof AST_SymbolFunarg)) {
+                        mangleable_var(expr.value);
+                        return make_node(AST_SymbolRef, expr.name, expr.name);
+                    }
+                    if (referenced > 1 ? mangleable_var(expr.value) : !compressor.exposed(def)) {
                         return make_node(AST_SymbolRef, expr.name, expr.name);
                     }
                 } else if (expr instanceof AST_Assign) {
@@ -1863,6 +1867,7 @@ merge(Compressor.prototype, {
                     found = true;
                     if (node instanceof AST_VarDef) {
                         node.value = null;
+                        if (value_def) value_def.replaced++;
                         return node;
                     }
                     return in_list ? List.skip : null;
index fd421a2..1c3af6f 100644 (file)
@@ -2205,8 +2205,8 @@ var_defs: {
     }
     expect: {
         var f1 = function(x, y) {
-            var r = x + y, a = r * r - r, b = 7;
-            console.log(a + b);
+            var r = x + y, z = r * r - r, b = 7;
+            console.log(z + b);
         };
         f1("1", 0);
     }
@@ -2700,8 +2700,8 @@ toplevel_single_reference: {
     }
     expect: {
         for (var b in x) {
-            var a;
-            b(a = b);
+            var a = b;
+            b(b);
         }
     }
 }
@@ -4244,8 +4244,7 @@ issue_2497: {
             if (true)
                 for (var i = 0; i < 1; ++i)
                     for (var k = 0; k < 1; ++k) {
-                        value = 1;
-                        value = value ? value + 1 : 0;
+                        value = (value = 1) ? value + 1 : 0;
                     }
             else
                 for (i = 0; i < 1; ++i)
@@ -7807,3 +7806,119 @@ issue_3744: {
     }
     expect_stdout: "PASS"
 }
+
+assign_value_def: {
+    options = {
+        collapse_vars: true,
+        unused: true,
+    }
+    input: {
+        function f(a) {
+            while (1) {
+                var b = a[0], c = a[1];
+                d = b;
+                e = c;
+                if (c[0] - e[0] > c[1] - d[1]) break;
+                return "PASS";
+            }
+            var d, e;
+            return "FAIL";
+        }
+        console.log(f([
+            [ 1, 2 ],
+            [ 3, 4 ],
+        ]));
+    }
+    expect: {
+        function f(a) {
+            while (1) {
+                var b = a[0], c = a[1];
+                if (c[0] - c[0] > c[1] - b[1]) break;
+                return "PASS";
+            }
+            return "FAIL";
+        }
+        console.log(f([
+            [ 1, 2 ],
+            [ 3, 4 ],
+        ]));
+    }
+    expect_stdout: "PASS"
+}
+
+join_vars_value_def: {
+    options = {
+        collapse_vars: true,
+        join_vars: true,
+        unused: true,
+    }
+    input: {
+        function f(a) {
+            while (1) {
+                var b = a[0], c = a[1];
+                d = b;
+                e = c;
+                if (c[0] - e[0] > c[1] - d[1]) break;
+                return "PASS";
+            }
+            var d, e;
+            return "FAIL";
+        }
+        console.log(f([
+            [ 1, 2 ],
+            [ 3, 4 ],
+        ]));
+    }
+    expect: {
+        function f(a) {
+            while (1) {
+                var b = a[0], c = a[1];
+                if (c[0] - c[0] > c[1] - b[1]) break;
+                return "PASS";
+            }
+            return "FAIL";
+        }
+        console.log(f([
+            [ 1, 2 ],
+            [ 3, 4 ],
+        ]));
+    }
+    expect_stdout: "PASS"
+}
+
+var_value_def: {
+    options = {
+        collapse_vars: true,
+        unused: true,
+    }
+    input: {
+        function f(a) {
+            while (1) {
+                var b = a[0], c = a[1], d = b, e = c;
+                if (c[0] - e[0] > c[1] - d[1]) break;
+                return "PASS";
+            }
+            var d, e;
+            return "FAIL";
+        }
+        console.log(f([
+            [ 1, 2 ],
+            [ 3, 4 ],
+        ]));
+    }
+    expect: {
+        function f(a) {
+            while (1) {
+                var b = a[0], c = a[1];
+                if (c[0] - c[0] > c[1] - b[1]) break;
+                return "PASS";
+            }
+            return "FAIL";
+        }
+        console.log(f([
+            [ 1, 2 ],
+            [ 3, 4 ],
+        ]));
+    }
+    expect_stdout: "PASS"
+}