aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2021-07-05 19:43:09 +0100
committerGitHub <noreply@github.com>2021-07-06 02:43:09 +0800
commitd0e3f6955d956a4977d701e9027eb54d15b6f77c (patch)
tree868f95638628a5b5d79a306bf1a5ee1e5afe7360
parent6961c57d1e2849b4c7c9e43295015d0bee44daa5 (diff)
downloadtracifyjs-d0e3f6955d956a4977d701e9027eb54d15b6f77c.tar.gz
tracifyjs-d0e3f6955d956a4977d701e9027eb54d15b6f77c.zip
enhance `functions` (#5052)
-rw-r--r--lib/compress.js45
-rw-r--r--test/compress/functions.js30
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,