fix corner case in `reduce_vars` & `unused` (#4208)
authorAlex Lam S.L <alexlamsl@gmail.com>
Mon, 12 Oct 2020 23:32:17 +0000 (00:32 +0100)
committerGitHub <noreply@github.com>
Mon, 12 Oct 2020 23:32:17 +0000 (07:32 +0800)
fixes #4207

lib/compress.js
test/compress/const.js

index bc01ebc..c59e26e 100644 (file)
@@ -165,10 +165,12 @@ Compressor.prototype = new TreeTransformer;
 merge(Compressor.prototype, {
     option: function(key) { return this.options[key] },
     exposed: function(def) {
-        if (def.global) for (var i = 0; i < def.orig.length; i++)
-            if (!this.toplevel[def.orig[i] instanceof AST_SymbolDefun ? "funcs" : "vars"])
-                return true;
-        return def.undeclared;
+        if (def.undeclared) return true;
+        if (!(def.global || def.scope.resolve() instanceof AST_Toplevel)) return false;
+        var toplevel = this.toplevel;
+        return !all(def.orig, function(sym) {
+            return toplevel[sym instanceof AST_SymbolDefun ? "funcs" : "vars"];
+        });
     },
     compress: function(node) {
         node = node.resolve_defines(this);
@@ -6642,13 +6644,10 @@ merge(Compressor.prototype, {
             var node = defn.name;
             if (!node.fixed_value()) return false;
             var def = node.definition();
+            if (compressor.exposed(def)) return false;
             var scope = def.scope.resolve();
-            if (scope instanceof AST_Toplevel) {
-                if (!compressor.toplevel.vars) return false;
-                if (def.scope === scope) return true;
-                return !scope.variables.has(node.name) && !scope.globals.has(node.name);
-            }
             if (def.scope === scope) return true;
+            if (scope instanceof AST_Toplevel) return !scope.variables.has(node.name) && !scope.globals.has(node.name);
             var s = def.scope;
             do {
                 s = s.parent_scope;
index d1164cc..aedfdbc 100644 (file)
@@ -909,3 +909,24 @@ issue_4205: {
     }
     expect_stdout: true
 }
+
+issue_4207: {
+    options = {
+        reduce_funcs: true,
+        reduce_vars: true,
+        unused: true,
+    }
+    input: {
+        {
+            const a = function() {};
+            console.log(a.length);
+        }
+    }
+    expect: {
+        {
+            const a = function() {};
+            console.log(a.length);
+        }
+    }
+    expect_stdout: "0"
+}