fix corner case in `functions` (#4619)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sun, 7 Feb 2021 05:52:09 +0000 (05:52 +0000)
committerGitHub <noreply@github.com>
Sun, 7 Feb 2021 05:52:09 +0000 (13:52 +0800)
fixes #4618

lib/compress.js
test/compress/awaits.js

index d4cf0da..7a6a0bc 100644 (file)
@@ -5854,13 +5854,7 @@ merge(Compressor.prototype, {
                             && var_defs[sym.id] == 1
                             && sym.assignments == 0
                             && (value instanceof AST_AsyncFunction || value instanceof AST_Function)
-                            && (sym.references.length ? all(sym.references, function(ref) {
-                                    return value === ref.fixed_value();
-                                }) : value === def.name.fixed_value())
-                            && (!value.name || (old_def = value.name.definition()).assignments == 0
-                                && (old_def.name == def.name.name || all(old_def.references, function(ref) {
-                                    return ref.scope.find_variable(def.name.name) === def.name.definition();
-                                })))
+                            && assigned_once(value, sym.references)
                             && can_declare_defun()
                             && can_rename(value, def.name.name)) {
                             AST_Node.warn("Declaring {name} as function [{file}:{line},{col}]", template(def.name));
@@ -5902,14 +5896,11 @@ merge(Compressor.prototype, {
                         sym.eliminated++;
                     }
 
-                    function is_catch(node) {
-                        var sym = node.definition();
-                        return sym.orig[0] instanceof AST_SymbolCatch && sym.scope.resolve() === node.scope.resolve();
-                    }
-
-                    function can_rename(fn, name) {
-                        var def = fn.variables.get(name);
-                        return !def || fn.name && def === fn.name.definition();
+                    function assigned_once(fn, refs) {
+                        if (refs.length == 0) return fn === def.name.fixed_value();
+                        return all(refs, function(ref) {
+                            return fn === ref.fixed_value();
+                        });
                     }
 
                     function can_declare_defun() {
@@ -5919,6 +5910,22 @@ merge(Compressor.prototype, {
                             || parent instanceof AST_If;
                     }
 
+                    function can_rename(fn, name) {
+                        if (!fn.name) return !fn.variables.get(name);
+                        old_def = fn.name.definition();
+                        if (old_def.assignments > 0) return false;
+                        if (old_def.name == name) return true;
+                        if (name == "await" && is_async(fn)) return false;
+                        return all(old_def.references, function(ref) {
+                            return ref.scope.find_variable(name) === sym;
+                        });
+                    }
+
+                    function is_catch(node) {
+                        var sym = node.definition();
+                        return sym.orig[0] instanceof AST_SymbolCatch && sym.scope.resolve() === node.scope.resolve();
+                    }
+
                     function flush() {
                         if (side_effects.length > 0) {
                             if (tail.length == 0) {
index 18012b4..7773599 100644 (file)
@@ -1218,3 +1218,31 @@ issue_4598: {
     expect_stdout: "PASS"
     node_version: ">=8"
 }
+
+issue_4618: {
+    options = {
+        functions: true,
+        reduce_vars: true,
+        unused: true,
+    }
+    input: {
+        console.log(typeof function() {
+            var await = async function f() {
+                console || f();
+            };
+            console.log;
+            return await;
+        }());
+    }
+    expect: {
+        console.log(typeof function() {
+            var await = async function f() {
+                console || f();
+            };
+            console.log;
+            return await;
+        }());
+    }
+    expect_stdout: "function"
+    node_version: ">=8"
+}