if (save) fixed = compressor.option("rests") && function() {
var value = save();
if (!(value instanceof AST_Array)) return node;
+ for (var i = 0, len = node.elements.length; i < len; i++) {
+ if (value.elements[i] instanceof AST_Spread) return node;
+ }
if (!fixed_node) fixed_node = make_node(AST_Array, node);
- fixed_node.elements = value.elements.slice(node.elements.length);
+ fixed_node.elements = value.elements.slice(len);
return fixed_node;
};
node.rest.walk(scanner);
unused_fn_names.push(node);
}
if (!(node instanceof AST_Accessor)) {
- if (node.rest) {
- var rest = node.rest.transform(trimmer);
+ var args, spread;
+ if (parent instanceof AST_Call && parent.expression === node) {
+ args = parent.args;
+ for (spread = 0; spread < args.length; spread++) {
+ if (args[spread] instanceof AST_Spread) break;
+ }
+ }
+ var argnames = node.argnames;
+ var rest = node.rest;
+ if (rest) {
+ if (!args || spread < argnames.length || rest instanceof AST_SymbolFunarg) {
+ rest = rest.transform(trimmer);
+ } else {
+ var trimmed = trim_destructured(rest, make_node(AST_Array, parent, {
+ elements: args.slice(argnames.length),
+ }), function(node) {
+ return node.definition().id in in_use_ids ? node : null;
+ }, !node.uses_arguments, rest);
+ rest = trimmed.name;
+ args.length = argnames.length;
+ if (trimmed.value.elements.length) [].push.apply(args, trimmed.value.elements);
+ }
if (rest instanceof AST_Destructured && !rest.rest
&& (!node.uses_arguments || tt.has_directive("use strict"))) {
if (rest instanceof AST_DestructuredArray) {
}
node.rest = rest;
}
- var argnames = node.argnames;
var trim = compressor.drop_fargs(node, parent) && !node.rest;
var default_length = trim ? -1 : node.length();
for (var i = argnames.length; --i >= 0;) {
var sym = argnames[i];
- if (!(sym instanceof AST_SymbolFunarg)) {
- var arg = sym.transform(trimmer);
- if (arg) {
+ if (sym instanceof AST_SymbolFunarg) {
+ var def = sym.definition();
+ if (def.id in in_use_ids) {
+ trim = false;
+ if (indexOf_assign(def, sym) < 0) sym.unused = null;
+ } else if (trim) {
+ log(sym, "Dropping unused function argument {name}");
+ argnames.pop();
+ } else {
+ sym.unused = true;
+ }
+ } else {
+ var funarg;
+ if (!args || spread < i) {
+ funarg = sym.transform(trimmer);
+ } else {
+ funarg = trim_destructured(sym, args[i], function(node) {
+ return node.definition().id in in_use_ids ? node : null;
+ }, !node.uses_arguments, sym).name;
+ }
+ if (funarg) {
trim = false;
} else if (trim) {
- log(sym.name, "Dropping unused default argument {name}");
+ log_default(sym, "Dropping unused default argument {name}");
argnames.pop();
} else if (i > default_length) {
- log(sym.name, "Dropping unused default argument assignment {name}");
- sym.name.unused = true;
+ log_default(sym, "Dropping unused default argument assignment {name}");
+ if (sym.name instanceof AST_SymbolFunarg) sym.name.unused = true;
argnames[i] = sym.name;
} else {
- log(sym.name, "Dropping unused default argument value {name}");
+ log_default(sym, "Dropping unused default argument value {name}");
sym.value = make_node(AST_Number, sym, { value: 0 });
}
- continue;
- }
- var def = sym.definition();
- if (def.id in in_use_ids) {
- trim = false;
- if (indexOf_assign(def, sym) < 0) sym.unused = null;
- } else if (trim) {
- log(sym, "Dropping unused function argument {name}");
- argnames.pop();
- } else {
- sym.unused = true;
}
}
fns_with_marked_args.push(node);
AST_Node[sym.definition().references.length > 0 ? "info" : "warn"](text + " [{file}:{line},{col}]", template(sym));
}
+ function log_default(node, text) {
+ if (node.name instanceof AST_SymbolFunarg) {
+ log(node.name, text);
+ } else {
+ AST_Node.info(text + " [{file}:{line},{col}]", {
+ name: node.print_to_string(),
+ file: node.start.file,
+ line: node.start.line,
+ col : node.start.col,
+ });
+ }
+ }
+
function template(sym) {
return {
name: sym.name,
return node;
}
- function trim_destructured(node, value, process, drop) {
+ function trim_destructured(node, value, process, drop, root) {
var trimmer = new TreeTransformer(function(node) {
if (node instanceof AST_DefaultValue) {
- if (compressor.option("default_values") && value && value.is_defined(compressor)) {
- node = node.name;
- } else {
+ if (!(compressor.option("default_values") && value && value.is_defined(compressor))) {
var save_drop = drop;
drop = false;
var trimmed = trim_default(trimmer, node);
drop = save_drop;
if (!trimmed && drop && value) value = value.drop_side_effect_free(compressor);
return trimmed;
+ } else if (node === root) {
+ root = node = node.name;
+ } else {
+ node = node.name;
}
}
if (node instanceof AST_DestructuredArray) {
if (!node.rest && (value instanceof AST_Array
|| value && value.is_string(compressor))) switch (elements.length) {
case 0:
+ if (node === root) break;
if (drop) value = value.drop_side_effect_free(compressor);
return null;
case 1:
if (!drop) break;
+ if (node === root) break;
var sym = elements[0];
if (sym.has_side_effects(compressor)) break;
if (value.has_side_effects(compressor) && sym.match_symbol(function(node) {
});
if (value && !node.rest) switch (properties.length) {
case 0:
+ if (node === root) break;
if (value.may_throw_on_access(compressor, true)) break;
if (drop) value = value.drop_side_effect_free(compressor);
return null;
case 1:
if (!drop) break;
+ if (node === root) break;
var prop = properties[0];
if (prop.key instanceof AST_Node) break;
if (prop.value.has_side_effects(compressor)) break;