@@ -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,28 +6697,11 @@ 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) {
|
||||
trim = false;
|
||||
} else if (trim) {
|
||||
log(sym.name, "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;
|
||||
argnames[i] = sym.name;
|
||||
} else {
|
||||
log(sym.name, "Dropping unused default argument value {name}");
|
||||
sym.value = make_node(AST_Number, sym, { value: 0 });
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (sym instanceof AST_SymbolFunarg) {
|
||||
var def = sym.definition();
|
||||
if (def.id in in_use_ids) {
|
||||
trim = false;
|
||||
@@ -6706,6 +6712,29 @@ Compressor.prototype.compress = function(node) {
|
||||
} 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_default(sym, "Dropping unused default argument {name}");
|
||||
argnames.pop();
|
||||
} else if (i > default_length) {
|
||||
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_default(sym, "Dropping unused default argument value {name}");
|
||||
sym.value = make_node(AST_Number, sym, { value: 0 });
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
||||
@@ -2038,3 +2038,59 @@ issue_5222: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5246_1: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function({} = 42) {
|
||||
return "PASS";
|
||||
}("foo"));
|
||||
}
|
||||
expect: {
|
||||
console.log(function({} = 0) {
|
||||
return "PASS";
|
||||
}("foo"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
expect_warnings: [
|
||||
"INFO: Dropping unused default argument value {}=42 [test/compress/default-values.js:1,29]",
|
||||
"INFO: Dropping unused default argument value {}=0 [test/compress/default-values.js:1,29]",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5246_2: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function f(a = "FAIL", [] = 42) {
|
||||
console.log(a);
|
||||
})("PASS", []);
|
||||
}
|
||||
expect: {
|
||||
(function(a = "FAIL", []) {
|
||||
console.log(a);
|
||||
})("PASS", []);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5246_3: {
|
||||
options = {
|
||||
default_values: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function f([ , {} ] = null){}([ , {} ]));
|
||||
}
|
||||
expect: {
|
||||
console.log(function([ {} ]){}([ {} ]));
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -359,7 +359,7 @@ retain_funarg_destructured_object_2: {
|
||||
expect: {
|
||||
console.log(function({ p: a, ... b }) {
|
||||
return b;
|
||||
}({ p: "FAIL" }).p || "PASS");
|
||||
}({}).p || "PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8.3.0"
|
||||
@@ -1104,7 +1104,7 @@ issue_5108: {
|
||||
expect: {
|
||||
console.log(function([]) {
|
||||
return "PASS";
|
||||
}([ "PASS", "FAIL" ]));
|
||||
}([]));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
@@ -1205,3 +1205,62 @@ issue_5165_2: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5246_1: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
rests: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof function([ , ...a ]) {
|
||||
return this && a;
|
||||
}([ , function(){} ])[0]);
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof function([]) {
|
||||
return this && [ function(){} ];
|
||||
}([])[0]);
|
||||
}
|
||||
expect_stdout: "function"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5246_2: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
rests: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
A = [ , "PASS", "FAIL" ];
|
||||
var [ , ...a ] = [ ... A ];
|
||||
console.log(a[0]);
|
||||
}
|
||||
expect: {
|
||||
A = [ , "PASS", "FAIL" ];
|
||||
var [ , ...a ] = [ ... A ];
|
||||
console.log(a[0]);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5246_3: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function f(...[ [ a ] ]) {
|
||||
console.log(a);
|
||||
})([ "PASS" ]);
|
||||
}
|
||||
expect: {
|
||||
(function(...[ a ]) {
|
||||
console.log(a);
|
||||
})([ "PASS" ][0]);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -1371,12 +1371,12 @@ issue_5034: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5076: {
|
||||
issue_5076_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_vars: true,
|
||||
passes: 2,
|
||||
pure_getters: "strict",
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
@@ -1393,13 +1393,41 @@ issue_5076: {
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
console.log("PASS");
|
||||
console.log("PASS"),
|
||||
a = 42["a"];
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5076_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_vars: true,
|
||||
passes: 2,
|
||||
pure_getters: "strict",
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
yields: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
console.log("PASS");
|
||||
var b = function*({
|
||||
p: {},
|
||||
}) {}({
|
||||
p: { a } = 42,
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5177: {
|
||||
options = {
|
||||
properties: true,
|
||||
|
||||
Reference in New Issue
Block a user