fix corner case in unused (#3716)
This commit is contained in:
123
lib/compress.js
123
lib/compress.js
@@ -4001,6 +4001,8 @@ merge(Compressor.prototype, {
|
||||
};
|
||||
// pass 3: we should drop declarations not in_use
|
||||
var unused_fn_names = [];
|
||||
var calls_to_drop_args = [];
|
||||
var fns_with_marked_args = [];
|
||||
var tt = new TreeTransformer(function(node, descend, in_list) {
|
||||
var parent = tt.parent();
|
||||
if (drop_vars) {
|
||||
@@ -4041,6 +4043,7 @@ merge(Compressor.prototype, {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node instanceof AST_Call) calls_to_drop_args.push(node);
|
||||
if (scope !== self) return;
|
||||
if (node instanceof AST_Function && node.name && drop_fn_name(node.name.definition())) {
|
||||
unused_fn_names.push(node);
|
||||
@@ -4059,6 +4062,7 @@ merge(Compressor.prototype, {
|
||||
trim = false;
|
||||
}
|
||||
}
|
||||
fns_with_marked_args.push(node);
|
||||
}
|
||||
if (drop_funcs && node instanceof AST_Defun && node !== self) {
|
||||
var def = node.name.definition();
|
||||
@@ -4252,6 +4256,9 @@ merge(Compressor.prototype, {
|
||||
unused_fn_names.forEach(function(fn) {
|
||||
fn.name = null;
|
||||
});
|
||||
calls_to_drop_args.forEach(function(call) {
|
||||
drop_unused_call_args(call, compressor, fns_with_marked_args);
|
||||
});
|
||||
|
||||
function log(sym, text, props) {
|
||||
AST_Node[sym.unreferenced() ? "warn" : "info"](text, props);
|
||||
@@ -5448,6 +5455,62 @@ merge(Compressor.prototype, {
|
||||
return make_sequence(node, x);
|
||||
}
|
||||
|
||||
function drop_unused_call_args(call, compressor, fns_with_marked_args) {
|
||||
var exp = call.expression;
|
||||
var fn = exp instanceof AST_SymbolRef ? exp.fixed_value() : exp;
|
||||
if (!(fn instanceof AST_Lambda)) return;
|
||||
if (fn.uses_arguments) return;
|
||||
if (fn.pinned()) return;
|
||||
if (fns_with_marked_args && fns_with_marked_args.indexOf(fn) < 0) return;
|
||||
var args = call.args;
|
||||
var pos = 0, last = 0;
|
||||
var drop_fargs = fn === exp && !fn.name && compressor.drop_fargs(fn, call);
|
||||
var side_effects = [];
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
var trim = i >= fn.argnames.length;
|
||||
if (trim || fn.argnames[i].__unused) {
|
||||
var node = args[i].drop_side_effect_free(compressor);
|
||||
if (drop_fargs) {
|
||||
fn.argnames.splice(i, 1);
|
||||
args.splice(i, 1);
|
||||
if (node) side_effects.push(node);
|
||||
i--;
|
||||
continue;
|
||||
} else if (node) {
|
||||
side_effects.push(node);
|
||||
args[pos++] = make_sequence(call, side_effects);
|
||||
side_effects = [];
|
||||
} else if (!trim) {
|
||||
if (side_effects.length) {
|
||||
node = make_sequence(call, side_effects);
|
||||
side_effects = [];
|
||||
} else {
|
||||
node = make_node(AST_Number, args[i], {
|
||||
value: 0
|
||||
});
|
||||
}
|
||||
args[pos++] = node;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
side_effects.push(args[i]);
|
||||
args[pos++] = make_sequence(call, side_effects);
|
||||
side_effects = [];
|
||||
}
|
||||
last = pos;
|
||||
}
|
||||
if (drop_fargs) for (; i < fn.argnames.length; i++) {
|
||||
if (fn.argnames[i].__unused) fn.argnames.splice(i--, 1);
|
||||
}
|
||||
args.length = last;
|
||||
if (!side_effects.length) return;
|
||||
var arg = make_sequence(call, side_effects);
|
||||
args.push(args.length < fn.argnames.length ? make_node(AST_UnaryPrefix, call, {
|
||||
operator: "void",
|
||||
expression: arg
|
||||
}) : arg);
|
||||
}
|
||||
|
||||
OPT(AST_Call, function(self, compressor) {
|
||||
var exp = self.expression;
|
||||
if (compressor.option("sequences")) {
|
||||
@@ -5464,63 +5527,7 @@ merge(Compressor.prototype, {
|
||||
if (seq !== self) return seq.optimize(compressor);
|
||||
}
|
||||
}
|
||||
var fn = exp;
|
||||
if (compressor.option("reduce_vars") && fn instanceof AST_SymbolRef) {
|
||||
fn = fn.fixed_value();
|
||||
}
|
||||
var is_func = fn instanceof AST_Lambda;
|
||||
if (compressor.option("unused")
|
||||
&& is_func
|
||||
&& !fn.uses_arguments
|
||||
&& !fn.pinned()) {
|
||||
var pos = 0, last = 0;
|
||||
var drop_fargs = exp === fn && !fn.name && compressor.drop_fargs(fn, self);
|
||||
var side_effects = [];
|
||||
for (var i = 0; i < self.args.length; i++) {
|
||||
var trim = i >= fn.argnames.length;
|
||||
if (trim || fn.argnames[i].__unused) {
|
||||
var node = self.args[i].drop_side_effect_free(compressor);
|
||||
if (drop_fargs) {
|
||||
fn.argnames.splice(i, 1);
|
||||
self.args.splice(i, 1);
|
||||
if (node) side_effects.push(node);
|
||||
i--;
|
||||
continue;
|
||||
} else if (node) {
|
||||
side_effects.push(node);
|
||||
self.args[pos++] = make_sequence(self, side_effects);
|
||||
side_effects = [];
|
||||
} else if (!trim) {
|
||||
if (side_effects.length) {
|
||||
node = make_sequence(self, side_effects);
|
||||
side_effects = [];
|
||||
} else {
|
||||
node = make_node(AST_Number, self.args[i], {
|
||||
value: 0
|
||||
});
|
||||
}
|
||||
self.args[pos++] = node;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
side_effects.push(self.args[i]);
|
||||
self.args[pos++] = make_sequence(self, side_effects);
|
||||
side_effects = [];
|
||||
}
|
||||
last = pos;
|
||||
}
|
||||
if (drop_fargs) for (; i < fn.argnames.length; i++) {
|
||||
if (fn.argnames[i].__unused) fn.argnames.splice(i--, 1);
|
||||
}
|
||||
self.args.length = last;
|
||||
if (side_effects.length) {
|
||||
var arg = make_sequence(self, side_effects);
|
||||
self.args.push(self.args.length < fn.argnames.length ? make_node(AST_UnaryPrefix, self, {
|
||||
operator: "void",
|
||||
expression: arg
|
||||
}) : arg);
|
||||
}
|
||||
}
|
||||
if (compressor.option("unused")) drop_unused_call_args(self, compressor);
|
||||
if (compressor.option("unsafe")) {
|
||||
if (is_undeclared_ref(exp)) switch (exp.name) {
|
||||
case "Array":
|
||||
@@ -5786,6 +5793,8 @@ merge(Compressor.prototype, {
|
||||
}
|
||||
}
|
||||
}
|
||||
var fn = exp instanceof AST_SymbolRef ? exp.fixed_value() : exp;
|
||||
var is_func = fn instanceof AST_Lambda;
|
||||
var stat = is_func && fn.first_statement();
|
||||
var can_inline = compressor.option("inline") && !self.is_expr_pure(compressor);
|
||||
if (exp === fn && can_inline && stat instanceof AST_Return) {
|
||||
|
||||
Reference in New Issue
Block a user