From d47ea77811c5b5935578e29203db99739683f5f5 Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Thu, 28 May 2020 13:07:36 +0100 Subject: [PATCH] fix corner case in `functions` (#3930) fixes #3929 --- lib/compress.js | 24 +++++++++++----------- test/compress/functions.js | 41 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index cc2d1ecb..9ddbfa43 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -4360,7 +4360,7 @@ merge(Compressor.prototype, { if (def.value && indexOf_assign(sym, def) < 0) { def.value = def.value.drop_side_effect_free(compressor); } - var var_defs = var_defs_by_id.get(sym.id); + var old_def, var_defs = var_defs_by_id.get(sym.id); if (!def.value) { if (var_defs.length > 1) { AST_Node.warn("Dropping duplicated declaration of variable {name} [{file}:{line},{col}]", template(def.name)); @@ -4375,23 +4375,23 @@ merge(Compressor.prototype, { && sym.assignments == 0 && def.value === def.name.fixed_value() && def.value instanceof AST_Function - && !(def.value.name && def.value.name.definition().assignments) + && (!def.value.name || (old_def = 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) === def.name.definition(); + }))) && can_rename(def.value, def.name.name) && (!compressor.has_directive("use strict") || parent instanceof AST_Scope)) { AST_Node.warn("Declaring {name} as function [{file}:{line},{col}]", template(def.name)); var defun = make_node(AST_Defun, def, def.value); defun.name = make_node(AST_SymbolDefun, def.name, def.name); var name_def = def.name.scope.resolve().def_function(defun.name); - if (def.value.name) { - var old_def = def.value.name.definition(); - def.value.walk(new TreeWalker(function(node) { - if (node instanceof AST_SymbolRef && node.definition() === old_def) { - node.name = name_def.name; - node.thedef = name_def; - node.reference({}); - } - })); - } + if (old_def) def.value.walk(new TreeWalker(function(node) { + if (node instanceof AST_SymbolRef && node.definition() === old_def) { + node.name = name_def.name; + node.thedef = name_def; + node.reference({}); + } + })); body.push(defun); } else { if (var_defs.length > 1 && sym.orig.indexOf(def.name) > sym.eliminated) { diff --git a/test/compress/functions.js b/test/compress/functions.js index 7ad6ff03..9607c593 100644 --- a/test/compress/functions.js +++ b/test/compress/functions.js @@ -4705,3 +4705,44 @@ issue_3911: { } expect_stdout: "PASS" } + +issue_3929: { + options = { + functions: true, + reduce_vars: true, + unused: true, + } + input: { + (function() { + var abc = function f() { + (function() { + switch (f) { + default: + var abc = 0; + case 0: + abc.p; + } + console.log(typeof f); + })(); + }; + typeof abc && abc(); + })(); + } + expect: { + (function() { + var abc = function f() { + (function() { + switch (f) { + default: + var abc = 0; + case 0: + abc.p; + } + console.log(typeof f); + })(); + }; + typeof abc && abc(); + })(); + } + expect_stdout: "function" +} -- 2.34.1