diff --git a/lib/compress.js b/lib/compress.js index 884f63ab..9d54406e 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -3111,7 +3111,11 @@ merge(Compressor.prototype, { OPT(AST_Call, function(self, compressor){ var exp = self.expression; var fn = exp; + var simple_args = all(self.args, function(arg) { + return !(arg instanceof AST_Expansion); + }); if (compressor.option("unused") + && simple_args && (fn instanceof AST_Function || compressor.option("reduce_vars") && fn instanceof AST_SymbolRef @@ -3120,6 +3124,18 @@ merge(Compressor.prototype, { && !fn.uses_eval) { var pos = 0, last = 0; for (var i = 0, len = self.args.length; i < len; i++) { + if (fn.argnames[i] instanceof AST_Expansion) { + if (fn.argnames[i].__unused) while (i < len) { + var node = self.args[i++].drop_side_effect_free(compressor); + if (node) { + self.args[pos++] = node; + } + } else while (i < len) { + self.args[pos++] = self.args[i++]; + } + last = pos; + break; + } var trim = i >= fn.argnames.length; if (trim || fn.argnames[i].__unused) { var node = self.args[i].drop_side_effect_free(compressor); @@ -3340,6 +3356,7 @@ merge(Compressor.prototype, { && exp.body.length == 1 && !exp.uses_arguments && !exp.uses_eval + && simple_args && !self.has_pure_annotation(compressor)) { var value; if (stat instanceof AST_Return) { @@ -3357,6 +3374,16 @@ merge(Compressor.prototype, { if (exp.argnames.length > 0) { fn.body.push(make_node(AST_Var, self, { definitions: exp.argnames.map(function(sym, i) { + if (sym instanceof AST_Expansion) { + return make_node(AST_VarDef, sym, { + name: sym.expression, + value: make_node(AST_Array, self, { + elements: self.args.slice(i).map(function(arg) { + return arg.clone(true); + }) + }) + }); + } var arg = self.args[i]; return make_node(AST_VarDef, sym, { name: sym, @@ -3365,7 +3392,7 @@ merge(Compressor.prototype, { }) })); } - if (self.args.length > exp.argnames.length) { + if (self.args.length > exp.argnames.length && !(exp.argnames[exp.argnames.length - 1] instanceof AST_Expansion)) { fn.body.push(make_node(AST_SimpleStatement, self, { body: make_sequence(self, self.args.slice(exp.argnames.length).map(function(node) { return node.clone(true); diff --git a/test/compress/drop-unused.js b/test/compress/drop-unused.js index 34b74908..081df308 100644 --- a/test/compress/drop-unused.js +++ b/test/compress/drop-unused.js @@ -1338,3 +1338,74 @@ issue_2105: { } expect_stdout: "PASS" } + +issue_2136_1: { + options = { + inline: true, + unused: true, + } + input: { + !function(a, ...b) { + console.log(b); + }(); + } + expect: { + !function(a, ...b) { + console.log(b); + }(); + } + expect_stdout: "[]" + node_version: ">=6" +} + +issue_2136_2: { + options = { + collapse_vars: true, + inline: true, + side_effects: true, + unused: true, + } + input: { + function f(x) { + console.log(x); + } + !function(a, ...b) { + f(b[0]); + }(1, 2, 3); + } + expect: { + function f(x) { + console.log(x); + } + f([2,3][0]); + } + expect_stdout: "2" + node_version: ">=6" +} + +issue_2136_3: { + options = { + collapse_vars: true, + evaluate: true, + inline: true, + passes: 3, + reduce_vars: true, + side_effects: true, + toplevel: true, + unsafe: true, + unused: true, + } + input: { + function f(x) { + console.log(x); + } + !function(a, ...b) { + f(b[0]); + }(1, 2, 3); + } + expect: { + console.log(2); + } + expect_stdout: "2" + node_version: ">=6" +}