aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2020-05-03 15:52:43 +0100
committerGitHub <noreply@github.com>2020-05-03 22:52:43 +0800
commitac429dc8e1a3d49af8fd3627449bd22ffd781f20 (patch)
tree93065f9112d51df13644949e7836436cfd93ef82 /lib
parent3766d5c9621f56dc01176670b7d0bd0c7ef0b325 (diff)
downloadtracifyjs-ac429dc8e1a3d49af8fd3627449bd22ffd781f20.tar.gz
tracifyjs-ac429dc8e1a3d49af8fd3627449bd22ffd781f20.zip
enhance `reduce_vars` (#3843)
Diffstat (limited to 'lib')
-rw-r--r--lib/compress.js70
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())) {