fix corner case in `collapse_vars` (#3898)
authorAlex Lam S.L <alexlamsl@gmail.com>
Thu, 14 May 2020 17:09:54 +0000 (18:09 +0100)
committerGitHub <noreply@github.com>
Thu, 14 May 2020 17:09:54 +0000 (01:09 +0800)
fixes #3897

lib/compress.js
test/compress/collapse_vars.js

index 93dbe06..36a04a7 100644 (file)
@@ -1855,7 +1855,12 @@ merge(Compressor.prototype, {
             }
 
             function foldable(expr) {
+                var lhs_ids = Object.create(null);
+                var marker = new TreeWalker(function(node) {
+                    if (node instanceof AST_SymbolRef) lhs_ids[node.definition().id] = true;
+                });
                 while (expr instanceof AST_Assign && expr.operator == "=") {
+                    expr.left.walk(marker);
                     expr = expr.right;
                 }
                 if (expr instanceof AST_SymbolRef) {
@@ -1871,12 +1876,9 @@ merge(Compressor.prototype, {
                 if (!(lhs instanceof AST_SymbolRef)) return false;
                 if (!invariant(expr)) return false;
                 var circular;
-                var def = lhs.definition();
                 expr.walk(new TreeWalker(function(node) {
                     if (circular) return true;
-                    if (node instanceof AST_SymbolRef && node.definition() === def) {
-                        circular = true;
-                    }
+                    if (node instanceof AST_SymbolRef && lhs_ids[node.definition().id]) circular = true;
                 }));
                 return !circular && rhs_exact_match;
 
index 0dd8754..97975b1 100644 (file)
@@ -8050,3 +8050,37 @@ issue_3894: {
         "PASS",
     ]
 }
+
+issue_3897: {
+    options = {
+        collapse_vars: true,
+    }
+    input: {
+        var a = 0;
+        (function() {
+            function f(b) {
+                b = a = 1 + a;
+                a = 1 + a;
+                console.log(b);
+            }
+            f();
+        })();
+        console.log(a);
+    }
+    expect: {
+        var a = 0;
+        (function() {
+            function f(b) {
+                b = a = 1 + a;
+                a = 1 + a;
+                console.log(b);
+            }
+            f();
+        })();
+        console.log(a);
+    }
+    expect_stdout: [
+        "1",
+        "2",
+    ]
+}