diff --git a/lib/compress/index.js b/lib/compress/index.js index a5ca5b229..180487b01 100644 --- a/lib/compress/index.js +++ b/lib/compress/index.js @@ -5214,6 +5214,17 @@ def_optimize(AST_Call, function(self, compressor) { var args = self.args.concat(value); return make_sequence(self, args).optimize(compressor); } + + // optimize identity function + if ( + fn.argnames.length === 1 + && self.args.length < 2 + && value.start.type === "name" + && value.name === fn.argnames[0].name + ) { + // replace call with first argument or undefined if none passed + return (self.args[0] || make_node(AST_Undefined)).optimize(compressor); + } } if (can_inline) { var scope, in_loop, level = -1; diff --git a/test/compress/async.js b/test/compress/async.js index 69b00de36..5c97de30c 100644 --- a/test/compress/async.js +++ b/test/compress/async.js @@ -151,9 +151,9 @@ async_inline: { (async function(){ return await 3; })(); (async function(x){ await console.log(x); })(4); - function echo(x) { return x; } - echo( async function(){ return await 1; }() ); - echo( async function(x){ await console.log(x); }(2) ); + function invoke(x, y) { return x(y); } + invoke( async function(){ return await 1; } ); + invoke( async function(x){ await console.log(x); }, 2); function top() { console.log("top"); } top(); @@ -165,9 +165,9 @@ async_inline: { !async function(){await 3}(); !async function(x){await console.log(4)}(); - function echo(x){return x} - echo(async function(){return await 1}()); - echo(async function(x){await console.log(2)}()); + function invoke(x, y){return x(y)} + invoke(async function(){return await 1}); + invoke(async function(x){await console.log(x)}, 2); console.log("top"); diff --git a/test/compress/functions.js b/test/compress/functions.js index 47840fd22..86f86dd42 100644 --- a/test/compress/functions.js +++ b/test/compress/functions.js @@ -400,22 +400,22 @@ inner_ref: { input: { console.log(function(a) { return function() { - return a; + return a + 1; }(); }(1), function(a) { return function(a) { - return a; + return a === undefined; }(); }(2)); } expect: { - console.log(function(a) { - return a; - }(1), function(a) { - return a; + console.log(function (a) { + return a + 1; + }(1), function (a) { + return void 0 === a; }()); } - expect_stdout: "1 undefined" + expect_stdout: "2 true" } issue_2107: { @@ -2102,15 +2102,15 @@ duplicate_arg_var: { } input: { console.log(function(b) { - return b; + return b + "ING"; var b; }("PASS")); } expect: { - console.log((b = "PASS", b)); + console.log((b = "PASS", b + "ING")); var b; } - expect_stdout: "PASS" + expect_stdout: "PASSING" } issue_2737_1: { diff --git a/test/compress/identity.js b/test/compress/identity.js new file mode 100644 index 000000000..3234b44f2 --- /dev/null +++ b/test/compress/identity.js @@ -0,0 +1,164 @@ +inline_identity: { + options = { + inline: true, + reduce_vars: true, + unused: true, + toplevel: true + } + input: { + const id = x => x; + console.log(id(1), id(2)); + } + expect: { + console.log(1, 2); + } + expect_stdout: "1 2" +} + +inline_identity_function: { + options = { + inline: true, + reduce_vars: true, + unused: true, + toplevel: true + } + input: { + function id(x) { return x }; + console.log(id(1), id(2)); + } + expect: { + console.log(1, 2); + } + expect_stdout: "1 2" +} + +inline_identity_undefined: { + options = { + inline: true, + reduce_vars: true, + unused: true, + toplevel: true + } + input: { + const id = x => x; + console.log(id(), id(undefined)); + } + expect: { + console.log(void 0, void 0); + } + expect_stdout: "undefined undefined" +} + +inline_identity_extra_params: { + options = { + inline: true, + reduce_vars: true, + unused: true, + toplevel: true + } + input: { + const id = x => x; + console.log(id(1, console.log(2)), id(3, 4)); + } + expect: { + const id = x => x; + console.log(id(1, console.log(2)), 3); + } + expect_stdout: ["2", "1 3"] +} + +inline_identity_higher_order: { + options = { + inline: true, + reduce_vars: true, + unused: true, + toplevel: true + } + input: { + const id = x => x; + const inc = x => x + 1; + console.log(id(inc(1)), id(inc)(2)); + } + expect: { + const inc = x => x + 1; + console.log(inc(1), inc(2)); + } + expect_stdout: "2 3" +} + +inline_identity_inline_function: { + options = { + evaluate: true, + inline: true, + passes: 2, + reduce_vars: true, + unused: true, + toplevel: true + } + input: { + const id = x => x; + console.log(id(x => x + 1)(1), id((x => x + 1)(2))); + } + expect: { + console.log(2, 3); + } + expect_stdout: "2 3" +} + +inline_identity_duplicate_arg_var: { + options = { + inline: true, + reduce_vars: true, + unused: true, + toplevel: true + } + input: { + const id = x => { + return x; + var x; + }; + console.log(id(1), id(2)); + } + expect: { + console.log(1, 2); + } + expect_stdout: "1 2" +} + +inline_identity_inner_ref: { + options = { + inline: true, + reduce_vars: true, + unused: true, + toplevel: true + } + input: { + const id = a => (function() { return a; })(); + const undef = a => (a => a)(); + console.log(id(1), id(2), undef(3), undef(4)); + } + expect: { + console.log(1, 2, void 0, void 0); + } + expect_stdout: "1 2 undefined undefined" +} + +inline_identity_async: { + options = { + inline: true, + reduce_vars: true, + unused: true, + toplevel: true + } + input: { + const id = x => x; + id(async () => await 1)(); + id(async x => await console.log(2))(); + } + expect: { + (async () => await 1)(); + (async x => await console.log(2))(); + } + expect_stdout: "2" + node_version: ">=8" +} diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js index e6a9203e2..c9e94843a 100644 --- a/test/compress/reduce_vars.js +++ b/test/compress/reduce_vars.js @@ -1429,6 +1429,7 @@ defun_inline_3: { defun_call: { options = { + evaluate: true, inline: true, reduce_funcs: true, reduce_vars: true, @@ -1447,10 +1448,7 @@ defun_call: { } expect: { function f() { - return 4 + h(1) - h(4); - function h(a) { - return a; - } + return 1; } } }