improve fix for #4355 (#4357)
authorAlex Lam S.L <alexlamsl@gmail.com>
Thu, 10 Dec 2020 16:48:41 +0000 (16:48 +0000)
committerGitHub <noreply@github.com>
Thu, 10 Dec 2020 16:48:41 +0000 (00:48 +0800)
lib/compress.js
test/compress/loops.js

index 1bb6d54..fbf6036 100644 (file)
@@ -5096,6 +5096,38 @@ merge(Compressor.prototype, {
             return sym;
         };
         var assign_in_use = Object.create(null);
+        var find_variable = function(name) {
+            find_variable = compose(self, 0, noop);
+            return find_variable(name);
+
+            function compose(child, level, find) {
+                var parent = compressor.parent(level);
+                if (!parent) return find;
+                if (parent instanceof AST_DestructuredKeyVal) {
+                    var destructured = compressor.parent(level + 1);
+                    if (parent.key === child) {
+                        var fn = compressor.parent(level + 2);
+                        if (fn instanceof AST_Lambda) {
+                            return compose(fn, level + 3, fn.argnames.indexOf(destructured) >= 0 ? function(name) {
+                                var def = find(name);
+                                if (def) return def;
+                                def = fn.variables.get(name);
+                                if (def) {
+                                    var sym = def.orig[0];
+                                    if (sym instanceof AST_SymbolFunarg || sym instanceof AST_SymbolLambda) return def;
+                                }
+                            } : function(name) {
+                                return find(name) || fn.variables.get(name);
+                            });
+                        }
+                    }
+                    return compose(destructured, level + 2, find);
+                }
+                return compose(parent, level + 1, parent.variables ? function(name) {
+                    return find(name) || parent.variables.get(name);
+                } : find);
+            }
+        };
         var for_ins = Object.create(null);
         var in_use = [];
         var in_use_ids = Object.create(null); // avoid expensive linear scans of in_use
@@ -5761,33 +5793,6 @@ merge(Compressor.prototype, {
             if (init instanceof AST_SymbolRef) return init;
         }
 
-        function find_variable(name) {
-            var level = 0;
-            var scope = self;
-            while (true) {
-                var in_arg = false;
-                do {
-                    var parent = compressor.parent(level++);
-                    if (parent instanceof AST_DestructuredKeyVal && parent.key === scope) {
-                        var fn = compressor.parent(level + 1);
-                        if (fn instanceof AST_Lambda) {
-                            in_arg = fn.argnames.indexOf(compressor.parent(level)) >= 0;
-                            level += 2;
-                            scope = fn;
-                            break;
-                        }
-                    }
-                    if (!parent) return;
-                    scope = parent;
-                } while (!(scope instanceof AST_BlockScope));
-                var def = scope.variables.get(name);
-                if (!def) continue;
-                if (!in_arg) return def;
-                var sym = def.orig[0];
-                if (sym instanceof AST_SymbolFunarg || sym instanceof AST_SymbolLambda) return def;
-            }
-        }
-
         function scan_ref_scoped(node, descend, init) {
             if (node instanceof AST_Assign && node.left instanceof AST_SymbolRef) {
                 var def = node.left.definition();
index c16fa5b..acbc826 100644 (file)
@@ -1255,3 +1255,28 @@ issue_4240: {
     }
     expect_stdout: "PASS"
 }
+
+issue_4355: {
+    options = {
+        dead_code: true,
+        evaluate: true,
+        loops: true,
+        side_effects: true,
+        unused: true,
+    }
+    input: {
+        while (function() {
+            var a;
+            for (a in console.log("PASS"))
+                var b = 0;
+        }())
+            var c;
+    }
+    expect: {
+        (function() {
+            console.log("PASS");
+        })();
+        var c;
+    }
+    expect_stdout: "PASS"
+}