Skip to content

Commit

Permalink
compress apply() & call() of function (#2613)
Browse files Browse the repository at this point in the history
- `fn.apply(a, [ ... ])` => `fn.call(a, ...)`
- `fn.call(a, ... )` => `a, fn(...)`

where `fn` can be `function` literal or symbol reference linked through `reduce_vars`
  • Loading branch information
alexlamsl committed Dec 18, 2017
1 parent 0b0eac1 commit 8ddcbc3
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 0 deletions.
28 changes: 28 additions & 0 deletions lib/compress.js
Expand Up @@ -3857,6 +3857,34 @@ merge(Compressor.prototype, {
}
}
break;
case "apply":
if (self.args.length == 2 && self.args[1] instanceof AST_Array) {
var args = self.args[1].elements.slice();
args.unshift(self.args[0]);
return make_node(AST_Call, self, {
expression: make_node(AST_Dot, exp, {
expression: exp.expression,
property: "call"
}),
args: args
}).optimize(compressor);
}
break;
case "call":
var func = exp.expression;
if (func instanceof AST_SymbolRef) {
func = func.fixed_value();
}
if (func instanceof AST_Function && !func.contains_this()) {
return make_sequence(this, [
self.args[0],
make_node(AST_Call, self, {
expression: exp.expression,
args: self.args.slice(1)
})
]).optimize(compressor);
}
break;
}
}
if (compressor.option("unsafe_Func")
Expand Down
126 changes: 126 additions & 0 deletions test/compress/functions.js
Expand Up @@ -923,3 +923,129 @@ issue_2604_2: {
}
expect_stdout: "PASS"
}

unsafe_apply_1: {
options = {
inline: true,
passes: 2,
reduce_vars: true,
side_effects: true,
unsafe: true,
unused: true,
}
input: {
(function(a, b) {
console.log(a, b);
}).apply("foo", [ "bar" ]);
(function(a, b) {
console.log(this, a, b);
}).apply("foo", [ "bar" ]);
(function(a, b) {
console.log(a, b);
}).apply("foo", [ "bar" ], "baz");
}
expect: {
console.log("bar", void 0);
(function(a, b) {
console.log(this, a, b);
}).call("foo", "bar");
(function(a, b) {
console.log(a, b);
}).apply("foo", [ "bar" ], "baz");
}
expect_stdout: true
}

unsafe_apply_2: {
options = {
reduce_vars: true,
side_effects: true,
toplevel: true,
unsafe: true,
}
input: {
function foo() {
console.log(a, b);
}
var bar = function(a, b) {
console.log(this, a, b);
}
(function() {
foo.apply("foo", [ "bar" ]);
bar.apply("foo", [ "bar" ]);
})();
}
expect: {
function foo() {
console.log(a, b);
}
var bar = function(a, b) {
console.log(this, a, b);
}
(function() {
foo("bar");
bar.call("foo", "bar");
})();
}
expect_stdout: true
}

unsafe_call_1: {
options = {
inline: true,
passes: 2,
reduce_vars: true,
side_effects: true,
unsafe: true,
unused: true,
}
input: {
(function(a, b) {
console.log(a, b);
}).call("foo", "bar");
(function(a, b) {
console.log(this, a, b);
}).call("foo", "bar");
}
expect: {
console.log("bar", void 0);
(function(a, b) {
console.log(this, a, b);
}).call("foo", "bar");
}
expect_stdout: true
}

unsafe_call_2: {
options = {
reduce_vars: true,
side_effects: true,
toplevel: true,
unsafe: true,
}
input: {
function foo() {
console.log(a, b);
}
var bar = function(a, b) {
console.log(this, a, b);
}
(function() {
foo.call("foo", "bar");
bar.call("foo", "bar");
})();
}
expect: {
function foo() {
console.log(a, b);
}
var bar = function(a, b) {
console.log(this, a, b);
}
(function() {
foo("bar");
bar.call("foo", "bar");
})();
}
expect_stdout: true
}

0 comments on commit 8ddcbc3

Please sign in to comment.