fix variable scope determination (#3449)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sat, 5 Oct 2019 21:13:44 +0000 (05:13 +0800)
committerGitHub <noreply@github.com>
Sat, 5 Oct 2019 21:13:44 +0000 (05:13 +0800)
fixes #3444

lib/compress.js
test/compress/functions.js

index 09d416c..8eab20b 100644 (file)
@@ -3399,16 +3399,22 @@ merge(Compressor.prototype, {
         def(AST_Lambda, function(scope) {
             var self = this;
             var result = true;
-            self.walk(new TreeWalker(function(node) {
+            var inner_scopes = [];
+            self.walk(new TreeWalker(function(node, descend) {
                 if (!result) return true;
+                if (node instanceof AST_Scope && node !== self) {
+                    inner_scopes.push(node);
+                    descend();
+                    inner_scopes.pop();
+                    return true;
+                }
                 if (node instanceof AST_SymbolRef) {
                     if (self.inlined) {
                         result = false;
                         return true;
                     }
                     var def = node.definition();
-                    if (member(def, self.enclosed)
-                        && !self.variables.has(def.name)) {
+                    if (!self.variables.has(def.name) && !member(def.scope, inner_scopes)) {
                         if (scope) {
                             var scope_def = scope.find_variable(node);
                             if (def.undeclared ? !scope_def : scope_def === def) {
index 8229538..40a38c0 100644 (file)
@@ -3148,3 +3148,30 @@ issue_3402: {
         "function",
     ]
 }
+
+issue_3444: {
+    options = {
+        inline: true,
+        reduce_vars: true,
+        unused: true,
+    }
+    input: {
+        (function(h) {
+            return f;
+            function f() {
+                g();
+            }
+            function g() {
+                h("PASS");
+            }
+        })(console.log)();
+    }
+    expect: {
+        (function(h) {
+            return function() {
+                void h("PASS");
+            };
+        })(console.log)();
+    }
+    expect_stdout: "PASS"
+}