From d0e3f6955d956a4977d701e9027eb54d15b6f77c Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Mon, 5 Jul 2021 19:43:09 +0100 Subject: [PATCH] enhance `functions` (#5052) --- lib/compress.js | 45 ++++++++++++++++++++------------------ test/compress/functions.js | 30 +++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 21 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index e0b7597b..714d3cd7 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -519,6 +519,13 @@ merge(Compressor.prototype, { }); } + function walk_fn_def(tw, fn) { + var was_scanning = tw.fn_scanning; + tw.fn_scanning = fn; + fn.walk(tw); + tw.fn_scanning = was_scanning; + } + function mark_fn_def(tw, def, fn) { if (!HOP(fn, "safe_ids")) return; var marker = fn.safe_ids; @@ -526,29 +533,25 @@ merge(Compressor.prototype, { if (fn.parent_scope.resolve().may_call_this === return_true) return; if (marker) { var visited = member(fn, tw.fn_visited); - if (marker === tw.safe_ids) return !visited && walk_fn_def(tw, fn); - if (visited) { - fn.enclosed.forEach(function(d) { - if (fn.variables.get(d.name) === d) return; - if (safe_to_read(tw, d)) return; - d.single_use = false; - if (d.fixed instanceof AST_LambdaDefinition) return; - d.fixed = false; - }); - return; - } - } else if (!tw.in_loop && !(tw.fn_scanning && tw.fn_scanning !== def.scope.resolve())) { + if (marker === tw.safe_ids) { + if (!visited) walk_fn_def(tw, fn); + } else if (!visited) { + fn.safe_ids = false; + } else fn.enclosed.forEach(function(d) { + if (fn.variables.get(d.name) === d) return; + if (safe_to_read(tw, d)) return; + d.single_use = false; + var fixed = d.fixed; + if (typeof fixed == "function") fixed = fixed(); + if (fixed instanceof AST_Lambda && HOP(fixed, "safe_ids")) return; + d.fixed = false; + }); + } else if (tw.fn_scanning && tw.fn_scanning !== def.scope.resolve()) { + fn.safe_ids = false; + } else { fn.safe_ids = tw.safe_ids; - return walk_fn_def(tw, fn); + walk_fn_def(tw, fn); } - fn.safe_ids = false; - } - - function walk_fn_def(tw, fn) { - var was_scanning = tw.fn_scanning; - tw.fn_scanning = fn; - fn.walk(tw); - tw.fn_scanning = was_scanning; } function pop_scope(tw, scope) { diff --git a/test/compress/functions.js b/test/compress/functions.js index 6e75e8fb..6d41a265 100644 --- a/test/compress/functions.js +++ b/test/compress/functions.js @@ -2826,6 +2826,36 @@ functions_use_strict: { expect_stdout: "a true 42 function function function" } +functions_cross_scope_reference: { + options = { + functions: true, + reduce_vars: true, + toplevel: true, + unused: true, + } + input: { + log = function(fn) { + console.log(typeof fn()); + }; + var a = function() {}; + function f() { + return a; + } + while (log(f)); + } + expect: { + log = function(fn) { + console.log(typeof fn()); + }; + function a() {} + function f() { + return a; + } + while (log(f)); + } + expect_stdout: "function" +} + functions_inner_var: { options = { functions: true,