fix corner case in `functions` (#4192)
authorAlex Lam S.L <alexlamsl@gmail.com>
Mon, 12 Oct 2020 01:26:56 +0000 (02:26 +0100)
committerGitHub <noreply@github.com>
Mon, 12 Oct 2020 01:26:56 +0000 (09:26 +0800)
fixes #4191

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

index 0493237..7d5e022 100644 (file)
@@ -4746,7 +4746,8 @@ merge(Compressor.prototype, {
                     node.definitions.forEach(function(defn) {
                         var def = defn.name.definition();
                         var_defs_by_id.add(def.id, defn);
-                        if (!drop_vars && !(def.id in in_use_ids)) {
+                        if ((!drop_vars || (node instanceof AST_Const ? def.redefined() : def.const_redefs))
+                            && !(def.id in in_use_ids)) {
                             in_use_ids[def.id] = true;
                             in_use.push(def);
                         }
@@ -4776,14 +4777,7 @@ merge(Compressor.prototype, {
         // symbols (that may not be in_use).
         tw = new TreeWalker(scan_ref_scoped);
         for (var i = 0; i < in_use.length; i++) {
-            var in_use_def = in_use[i];
-            if (in_use_def.const_redefs) in_use_def.const_redefs.forEach(function(def) {
-                if (!(def.id in in_use_ids)) {
-                    in_use_ids[def.id] = true;
-                    in_use.push(def);
-                }
-            });
-            var init = initializations.get(in_use_def.id);
+            var init = initializations.get(in_use[i].id);
             if (init) init.forEach(function(init) {
                 init.walk(tw);
             });
@@ -4944,6 +4938,7 @@ merge(Compressor.prototype, {
                             }
                         } else if (compressor.option("functions")
                             && !compressor.option("ie8")
+                            && !(node instanceof AST_Const)
                             && var_defs.length == 1
                             && sym.assignments == 0
                             && def.value instanceof AST_Function
index fa55864..c3bb3fa 100644 (file)
@@ -240,12 +240,8 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
         }
         // ensure compression works if `const` reuses a scope variable
         if (node instanceof AST_SymbolConst) {
-            var def = node.definition();
-            var redef = def.redefined();
-            if (redef) {
-                if (!redef.const_redefs) redef.const_redefs = [];
-                redef.const_redefs.push(def);
-            }
+            var redef = node.definition().redefined();
+            if (redef) redef.const_redefs = true;
             return true;
         }
     });
index 265ca9f..bc37e14 100644 (file)
@@ -513,6 +513,7 @@ catch_ie8_2: {
     options = {
         dead_code: true,
         ie8: true,
+        passes: 2,
         toplevel: true,
         unused: true,
     }
@@ -665,3 +666,62 @@ drop_unused: {
     }
     expect_stdout: "undefined"
 }
+
+legacy_scope: {
+    options = {
+        toplevel: true,
+        unused: true,
+    }
+    input: {
+        {
+            const a = 42;
+        }
+        var a;
+    }
+    expect: {
+        {
+            const a = 42;
+        }
+        var a;
+    }
+    expect_stdout: true
+}
+
+issue_4191_1: {
+    options = {
+        functions: true,
+        reduce_vars: true,
+        unused: true,
+    }
+    input: {
+        {
+            const a = function() {};
+        }
+        console.log(typeof a);
+    }
+    expect: {
+        {
+            const a = function() {};
+        }
+        console.log(typeof a);
+    }
+    expect_stdout: true
+}
+
+issue_4191_2: {
+    options = {
+        functions: true,
+        reduce_vars: true,
+        toplevel: true,
+        unused: true,
+    }
+    input: {
+        const a = function() {};
+        console.log(typeof a, a());
+    }
+    expect: {
+        function a() {};
+        console.log(typeof a, a());
+    }
+    expect_stdout: "function undefined"
+}