enhance collapse_vars (#3602)
authorAlex Lam S.L <alexlamsl@gmail.com>
Wed, 20 Nov 2019 04:54:49 +0000 (12:54 +0800)
committerGitHub <noreply@github.com>
Wed, 20 Nov 2019 04:54:49 +0000 (12:54 +0800)
lib/compress.js
test/compress/collapse_vars.js

index 4ce283d..43c32a7 100644 (file)
@@ -1151,7 +1151,7 @@ merge(Compressor.prototype, {
                         return node;
                     } else {
                         replaced++;
-                        if (value_def && candidate instanceof AST_VarDef) return node;
+                        if (value_def) return node;
                     }
                     CHANGED = abort = true;
                     AST_Node.info("Collapsing {name} [{file}:{line},{col}]", {
@@ -1207,7 +1207,7 @@ merge(Compressor.prototype, {
                     if (is_lhs(node, multi_replacer.parent())) return node;
                     def.replaced++;
                     value_def.replaced--;
-                    return candidate.value.clone();
+                    return get_rvalue(candidate).clone();
                 }
                 // Skip (non-executed) functions and (leading) default case in switch statements
                 if (node instanceof AST_Default || node instanceof AST_Scope) return node;
@@ -1255,10 +1255,17 @@ merge(Compressor.prototype, {
                         statements[i].transform(scanner);
                     }
                     if (value_def) {
-                        var def = candidate.name.definition();
-                        if (abort && def.references.length - def.replaced > replaced) replaced = false;
-                        else {
-                            abort = false;
+                        var def = lhs.definition();
+                        if (abort) {
+                            var referenced = def.references.length - def.replaced;
+                            if (candidate instanceof AST_Assign) referenced--;
+                            if (referenced > replaced) {
+                                replaced = false;
+                            } else {
+                                abort = false;
+                            }
+                        }
+                        if (!abort) {
                             hit_index = 0;
                             hit = funarg;
                             for (var i = stat_index; !abort && i < statements.length; i++) {
@@ -1334,7 +1341,7 @@ merge(Compressor.prototype, {
                     return compressor.option("ie8") && node.name && lvalues.has(node.name.name);
                 }
                 if (node instanceof AST_PropAccess) {
-                    return side_effects || node.expression.may_throw_on_access(compressor);
+                    return side_effects || !value_def && node.expression.may_throw_on_access(compressor);
                 }
                 if (node instanceof AST_SymbolRef) {
                     if (symbol_in_lvalues(node, parent)) {
index 81f2417..abdd9c2 100644 (file)
@@ -3852,10 +3852,9 @@ issue_2436_9: {
     expect: {
         var o = console;
         console.log({
-            x: (c = o).a,
-            y: c.b,
+            x: o.a,
+            y: o.b,
         });
-        var c;
     }
     expect_stdout: true
 }
@@ -6567,3 +6566,29 @@ issue_3596: {
     }
     expect_stdout: "42"
 }
+
+local_value_replacement: {
+    options = {
+        collapse_vars: true,
+        unused: true,
+    }
+    input: {
+        function f(a, b) {
+            (a = b) && g(a);
+        }
+        function g(c) {
+            console.log(c);
+        }
+        f("FAIL", "PASS");
+    }
+    expect: {
+        function f(a, b) {
+            (a = b) && g(a);
+        }
+        function g(c) {
+            console.log(c);
+        }
+        f("FAIL", "PASS");
+    }
+    expect_stdout: "PASS"
+}