diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2021-07-05 19:43:09 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-06 02:43:09 +0800 |
commit | d0e3f6955d956a4977d701e9027eb54d15b6f77c (patch) | |
tree | 868f95638628a5b5d79a306bf1a5ee1e5afe7360 | |
parent | 6961c57d1e2849b4c7c9e43295015d0bee44daa5 (diff) | |
download | tracifyjs-d0e3f6955d956a4977d701e9027eb54d15b6f77c.tar.gz tracifyjs-d0e3f6955d956a4977d701e9027eb54d15b6f77c.zip |
enhance `functions` (#5052)
-rw-r--r-- | lib/compress.js | 45 | ||||
-rw-r--r-- | 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, |