diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2020-05-03 15:52:43 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-03 22:52:43 +0800 |
commit | ac429dc8e1a3d49af8fd3627449bd22ffd781f20 (patch) | |
tree | 93065f9112d51df13644949e7836436cfd93ef82 /lib | |
parent | 3766d5c9621f56dc01176670b7d0bd0c7ef0b325 (diff) | |
download | tracifyjs-ac429dc8e1a3d49af8fd3627449bd22ffd781f20.tar.gz tracifyjs-ac429dc8e1a3d49af8fd3627449bd22ffd781f20.zip |
enhance `reduce_vars` (#3843)
Diffstat (limited to 'lib')
-rw-r--r-- | lib/compress.js | 70 |
1 files changed, 45 insertions, 25 deletions
diff --git a/lib/compress.js b/lib/compress.js index 394184bc..8b6c38dd 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -607,7 +607,13 @@ merge(Compressor.prototype, { def(AST_Call, function(tw, descend) { tw.find_parent(AST_Scope).may_call_this(); var exp = this.expression; - if (exp instanceof AST_SymbolRef) { + if (exp instanceof AST_Function) { + this.args.forEach(function(arg) { + arg.walk(tw); + }); + exp.walk(tw); + return true; + } else if (exp instanceof AST_SymbolRef) { var def = exp.definition(); if (this.TYPE == "Call" && tw.in_boolean_context()) def.bool_fn++; if (!(def.fixed instanceof AST_Defun)) return; @@ -706,23 +712,20 @@ merge(Compressor.prototype, { return true; }); def(AST_Function, function(tw, descend, compressor) { - var node = this; - node.inlined = false; - push(tw); - reset_variables(tw, compressor, node); + var fn = this; + fn.inlined = false; var iife; - if (!node.name - && (iife = tw.parent()) instanceof AST_Call - && iife.expression === node) { + if (!fn.name && (iife = tw.parent()) instanceof AST_Call && iife.expression === fn) { + 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. - node.argnames.forEach(function(arg, i) { + fn.argnames.forEach(function(arg, i) { var d = arg.definition(); - if (d.fixed === undefined && (!node.uses_arguments || tw.has_directive("use strict"))) { + if (d.fixed === undefined && (!fn.uses_arguments || tw.has_directive("use strict"))) { var value = iife.args[i]; d.fixed = function() { - var j = node.argnames.indexOf(arg); + var j = fn.argnames.indexOf(arg); if (j < 0) return value; return iife.args[j] || make_node(AST_Undefined, iife); }; @@ -732,10 +735,29 @@ merge(Compressor.prototype, { d.fixed = false; } }); + var has_return = false; + var visit = tw.visit; + tw.visit = function(node, descend) { + var ret = visit.call(tw, node, descend); + if (!has_return && node instanceof AST_Return && tw.find_parent(AST_Scope) === fn) { + has_return = true; + push(tw); + } + return ret; + }; + descend(); + tw.visit = visit; + var safe_ids = tw.safe_ids; + pop(tw); + walk_defuns(tw, fn); + if (!has_return) tw.safe_ids = safe_ids; + } else { + push(tw); + reset_variables(tw, compressor, fn); + descend(); + pop(tw); + walk_defuns(tw, fn); } - descend(); - pop(tw); - walk_defuns(tw, node); return true; }); def(AST_If, function(tw) { @@ -4512,17 +4534,15 @@ merge(Compressor.prototype, { } function scan_ref_scoped(node, descend, init) { - if (scope === self) { - if (node instanceof AST_Assign && node.left instanceof AST_SymbolRef) { - var node_def = node.left.definition(); - if (node.operator != "=") chained[node_def.id] = true; - match_assigns(node_def, node); - } - if (node instanceof AST_Unary && node.expression instanceof AST_SymbolRef) { - var node_def = node.expression.definition(); - chained[node_def.id] = true; - match_assigns(node_def, node); - } + if (node instanceof AST_Assign && node.left instanceof AST_SymbolRef) { + var node_def = node.left.definition(); + if (node.operator != "=") chained[node_def.id] = true; + match_assigns(node_def, node); + } + if (node instanceof AST_Unary && node.expression instanceof AST_SymbolRef) { + var node_def = node.expression.definition(); + chained[node_def.id] = true; + match_assigns(node_def, node); } var node_def, props = [], sym = assign_as_unused(node, props); if (sym && self.variables.get(sym.name) === (node_def = sym.definition())) { |