diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2020-12-17 22:18:47 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-18 06:18:47 +0800 |
commit | 4fa54b075c4507901fd3750e8fc7834cf7e9c809 (patch) | |
tree | 3e9ef13a3c3db1035115d7bf1ddee98577c7b0aa /lib/compress.js | |
parent | ab82be82b28c8fed0643569700d9b5ff2f093aea (diff) | |
download | tracifyjs-4fa54b075c4507901fd3750e8fc7834cf7e9c809.tar.gz tracifyjs-4fa54b075c4507901fd3750e8fc7834cf7e9c809.zip |
enhance `reduce_vars` (#4392)
Diffstat (limited to 'lib/compress.js')
-rw-r--r-- | lib/compress.js | 115 |
1 files changed, 56 insertions, 59 deletions
diff --git a/lib/compress.js b/lib/compress.js index 8fe0ad62..fa59ef5e 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -672,6 +672,53 @@ merge(Compressor.prototype, { return true; } + function reduce_iife(tw, descend, compressor) { + var fn = this; + fn.inlined = false; + var iife = tw.parent(); + var hit = fn instanceof AST_AsyncFunction; + var aborts = false; + fn.walk(new TreeWalker(function(node) { + if (hit) return aborts = true; + if (node instanceof AST_Return) return hit = true; + if (node instanceof AST_Scope && node !== fn) return true; + })); + if (aborts) push(tw); + reset_variables(tw, compressor, fn); + // Virtually turn IIFE parameters into variable definitions: + // (function(a,b) {...})(c,d) => (function() {var a=c,b=d; ...})() + // So existing transformation rules can work on them. + var safe = !fn.uses_arguments || tw.has_directive("use strict"); + fn.argnames.forEach(function(arg, i) { + var value = iife.args[i]; + scan_declaration(tw, arg, function() { + var j = fn.argnames.indexOf(arg); + return (j < 0 ? value : iife.args[j]) || make_node(AST_Undefined, iife); + }, function(node, fixed) { + var d = node.definition(); + if (safe && d.fixed === undefined) { + mark(tw, d); + tw.loop_ids[d.id] = tw.in_loop; + var value = iife.args[i]; + d.fixed = fixed; + d.fixed.assigns = [ arg ]; + } else { + d.fixed = false; + } + }); + }); + if (fn instanceof AST_Arrow && fn.value) { + fn.value.walk(tw); + } else { + walk_body(fn, tw); + } + var safe_ids = tw.safe_ids; + pop(tw); + walk_defuns(tw, fn); + if (!aborts) tw.safe_ids = safe_ids; + return true; + } + def(AST_Assign, function(tw, descend, compressor) { var node = this; var left = node.left; @@ -771,10 +818,14 @@ merge(Compressor.prototype, { tw.find_parent(AST_Scope).may_call_this(); var exp = this.expression; if (is_function(exp)) { + var iife = !exp.name; this.args.forEach(function(arg) { arg.walk(tw); + if (arg instanceof AST_Spread) iife = false; }); + if (iife) exp.reduce_vars = reduce_iife; exp.walk(tw); + if (iife) delete exp.reduce_vars; return true; } else if (exp instanceof AST_SymbolRef) { var def = exp.definition(); @@ -861,62 +912,6 @@ merge(Compressor.prototype, { tw.in_loop = saved_loop; return true; }); - def(AST_Function, function(tw, descend, compressor) { - var fn = this; - fn.inlined = false; - var iife; - if (!fn.name - && (iife = tw.parent()) instanceof AST_Call - && iife.expression === fn - && all(iife.args, function(arg) { - return !(arg instanceof AST_Spread); - })) { - var hit = false; - var aborts = false; - fn.walk(new TreeWalker(function(node) { - if (hit) return aborts = true; - if (node instanceof AST_Return) return hit = true; - if (node instanceof AST_Scope && node !== fn) return true; - })); - if (aborts) push(tw); - reset_variables(tw, compressor, fn); - // Virtually turn IIFE parameters into variable definitions: - // (function(a,b) {...})(c,d) => (function() {var a=c,b=d; ...})() - // So existing transformation rules can work on them. - var safe = !fn.uses_arguments || tw.has_directive("use strict"); - fn.argnames.forEach(function(arg, i) { - var value = iife.args[i]; - scan_declaration(tw, arg, function() { - var j = fn.argnames.indexOf(arg); - return (j < 0 ? value : iife.args[j]) || make_node(AST_Undefined, iife); - }, function(node, fixed) { - var d = node.definition(); - if (safe && d.fixed === undefined) { - mark(tw, d); - tw.loop_ids[d.id] = tw.in_loop; - var value = iife.args[i]; - d.fixed = fixed; - d.fixed.assigns = [ arg ]; - } else { - d.fixed = false; - } - }); - }); - walk_body(fn, tw); - var safe_ids = tw.safe_ids; - pop(tw); - walk_defuns(tw, fn); - if (!aborts) tw.safe_ids = safe_ids; - } else { - push(tw); - reset_variables(tw, compressor, fn); - descend(); - pop(tw); - if (fn.name) mark_escaped(tw, fn.name.definition(), fn, fn.name, fn, 0, 1); - walk_defuns(tw, fn); - } - return true; - }); def(AST_If, function(tw) { this.condition.walk(tw); push(tw); @@ -936,12 +931,14 @@ merge(Compressor.prototype, { return true; }); def(AST_Lambda, function(tw, descend, compressor) { - this.inlined = false; + var fn = this; + fn.inlined = false; push(tw); - reset_variables(tw, compressor, this); + reset_variables(tw, compressor, fn); descend(); pop(tw); - walk_defuns(tw, this); + if (fn.name) mark_escaped(tw, fn.name.definition(), fn, fn.name, fn, 0, 1); + walk_defuns(tw, fn); return true; }); def(AST_Switch, function(tw, descend, compressor) { |