fix corner cases in reduce_vars & unused (#5247)

fixes #5246
This commit is contained in:
Alex Lam S.L
2021-12-30 20:47:13 +00:00
committed by GitHub
parent 80d5f23fee
commit e7ce1051fe
4 changed files with 222 additions and 31 deletions

View File

@@ -784,8 +784,11 @@ Compressor.prototype.compress = function(node) {
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);
@@ -6662,8 +6665,28 @@ Compressor.prototype.compress = function(node) {
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) {
@@ -6674,37 +6697,43 @@ Compressor.prototype.compress = function(node) {
}
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);
@@ -7049,6 +7078,19 @@ Compressor.prototype.compress = function(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,
@@ -7245,18 +7287,20 @@ Compressor.prototype.compress = function(node) {
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) {
@@ -7319,10 +7363,12 @@ Compressor.prototype.compress = function(node) {
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) {
@@ -7446,11 +7492,13 @@ Compressor.prototype.compress = 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;