compress apply() & call() of function (#2613)
- `fn.apply(a, [ ... ])` => `fn.call(a, ...)` - `fn.call(a, ... )` => `a, fn(...)` where `fn` can be `function` literal or symbol reference linked through `reduce_vars`
This commit is contained in:
@@ -3857,6 +3857,34 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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")
|
if (compressor.option("unsafe_Func")
|
||||||
|
|||||||
@@ -923,3 +923,129 @@ issue_2604_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
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
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user