Skip to content

Commit

Permalink
fix #510: inline identity functions (#512)
Browse files Browse the repository at this point in the history
* fix #510: inline identity functions

* bringing back test semantics hidden by identity. simplifying identity optimization

* fix node 12 issue and don't drop extra args with side effects
  • Loading branch information
michens authored and fabiosantoscode committed Nov 23, 2019
1 parent d393ca6 commit 0ae57bd
Show file tree
Hide file tree
Showing 5 changed files with 193 additions and 20 deletions.
11 changes: 11 additions & 0 deletions lib/compress/index.js
Expand Up @@ -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;
Expand Down
12 changes: 6 additions & 6 deletions test/compress/async.js
Expand Up @@ -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();
Expand All @@ -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");

Expand Down
20 changes: 10 additions & 10 deletions test/compress/functions.js
Expand Up @@ -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: {
Expand Down Expand Up @@ -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: {
Expand Down
164 changes: 164 additions & 0 deletions 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"
}
6 changes: 2 additions & 4 deletions test/compress/reduce_vars.js
Expand Up @@ -1429,6 +1429,7 @@ defun_inline_3: {

defun_call: {
options = {
evaluate: true,
inline: true,
reduce_funcs: true,
reduce_vars: true,
Expand All @@ -1447,10 +1448,7 @@ defun_call: {
}
expect: {
function f() {
return 4 + h(1) - h(4);
function h(a) {
return a;
}
return 1;
}
}
}
Expand Down

0 comments on commit 0ae57bd

Please sign in to comment.