enhance inline (#3760)
This commit is contained in:
@@ -5813,12 +5813,24 @@ merge(Compressor.prototype, {
|
|||||||
var is_func = fn instanceof AST_Lambda;
|
var is_func = fn instanceof AST_Lambda;
|
||||||
var stat = is_func && fn.first_statement();
|
var stat = is_func && fn.first_statement();
|
||||||
var can_inline = compressor.option("inline") && !self.is_expr_pure(compressor);
|
var can_inline = compressor.option("inline") && !self.is_expr_pure(compressor);
|
||||||
if (exp === fn && can_inline && stat instanceof AST_Return) {
|
if (can_inline && stat instanceof AST_Return) {
|
||||||
var value = stat.value;
|
var value = stat.value;
|
||||||
if (!value || value.is_constant_expression()) {
|
if (exp === fn && (!value || value.is_constant_expression())) {
|
||||||
var args = self.args.concat(value || make_node(AST_Undefined, self));
|
var args = self.args.concat(value || make_node(AST_Undefined, self));
|
||||||
return make_sequence(self, args).optimize(compressor);
|
return make_sequence(self, args).optimize(compressor);
|
||||||
}
|
}
|
||||||
|
var funarg, pos;
|
||||||
|
if (value instanceof AST_SymbolRef
|
||||||
|
&& (funarg = resolve_funarg(value.definition().orig))
|
||||||
|
&& (pos = fn.argnames.indexOf(funarg)) >= 0
|
||||||
|
&& (pos >= self.args.length - 1 || all(self.args.slice(pos), function(funarg) {
|
||||||
|
return !funarg.has_side_effects(compressor);
|
||||||
|
}))) {
|
||||||
|
var args = self.args.slice();
|
||||||
|
args.push(args.splice(pos, 1)[0] || make_node(AST_Undefined, self));
|
||||||
|
var node = make_sequence(self, args).optimize(compressor);
|
||||||
|
return maintain_this_binding(compressor, compressor.parent(), compressor.self(), node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (is_func) {
|
if (is_func) {
|
||||||
var def, value, scope, in_loop, level = -1;
|
var def, value, scope, in_loop, level = -1;
|
||||||
@@ -5837,7 +5849,8 @@ merge(Compressor.prototype, {
|
|||||||
&& can_inject_symbols()) {
|
&& can_inject_symbols()) {
|
||||||
fn._squeezed = true;
|
fn._squeezed = true;
|
||||||
if (exp !== fn) fn.parent_scope = exp.scope;
|
if (exp !== fn) fn.parent_scope = exp.scope;
|
||||||
return make_sequence(self, flatten_fn()).optimize(compressor);
|
var node = make_sequence(self, flatten_fn()).optimize(compressor);
|
||||||
|
return maintain_this_binding(compressor, compressor.parent(), compressor.self(), node);
|
||||||
}
|
}
|
||||||
if (compressor.option("side_effects")
|
if (compressor.option("side_effects")
|
||||||
&& all(fn.body, is_empty)
|
&& all(fn.body, is_empty)
|
||||||
@@ -5864,6 +5877,14 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
return try_evaluate(compressor, self);
|
return try_evaluate(compressor, self);
|
||||||
|
|
||||||
|
function resolve_funarg(orig) {
|
||||||
|
var funarg;
|
||||||
|
for (var i = 0; orig[i] instanceof AST_SymbolFunarg; i++) {
|
||||||
|
funarg = orig[i];
|
||||||
|
}
|
||||||
|
return funarg;
|
||||||
|
}
|
||||||
|
|
||||||
function return_value(stat) {
|
function return_value(stat) {
|
||||||
if (!stat) return make_node(AST_Undefined, self);
|
if (!stat) return make_node(AST_Undefined, self);
|
||||||
if (stat instanceof AST_Return) {
|
if (stat instanceof AST_Return) {
|
||||||
|
|||||||
@@ -342,11 +342,7 @@ inner_ref: {
|
|||||||
}(2));
|
}(2));
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(function(a) {
|
console.log(1, void 0);
|
||||||
return a;
|
|
||||||
}(1), function(a) {
|
|
||||||
return a;
|
|
||||||
}());
|
|
||||||
}
|
}
|
||||||
expect_stdout: "1 undefined"
|
expect_stdout: "1 undefined"
|
||||||
}
|
}
|
||||||
@@ -1577,7 +1573,23 @@ issue_2663_3: {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
duplicate_argnames: {
|
duplicate_argnames_1: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a, a, a) {
|
||||||
|
return a;
|
||||||
|
}("FAIL", 42, "PASS"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
duplicate_argnames_2: {
|
||||||
options = {
|
options = {
|
||||||
inline: true,
|
inline: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
@@ -1857,10 +1869,9 @@ use_before_init_in_loop: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
duplicate_arg_var: {
|
duplicate_arg_var_1: {
|
||||||
options = {
|
options = {
|
||||||
inline: true,
|
inline: true,
|
||||||
toplevel: true,
|
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(function(b) {
|
console.log(function(b) {
|
||||||
@@ -1869,7 +1880,24 @@ duplicate_arg_var: {
|
|||||||
}("PASS"));
|
}("PASS"));
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log((b = "PASS", b));
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
duplicate_arg_var_2: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(b) {
|
||||||
|
return b + "SS";
|
||||||
|
var b;
|
||||||
|
}("PA"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log((b = "PA", b + "SS"));
|
||||||
var b;
|
var b;
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
@@ -3785,3 +3813,87 @@ issue_3679_3: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
preceding_side_effects: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a, b, c) {
|
||||||
|
return b;
|
||||||
|
}(console, "PASS", 42));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log((console, 42, "PASS"));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
trailing_side_effects: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a, b, c) {
|
||||||
|
return b;
|
||||||
|
}(42, "PASS", console));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a, b, c) {
|
||||||
|
return b;
|
||||||
|
}(42, "PASS", console));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
preserve_binding_1: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
f: function() {
|
||||||
|
return this === o ? "FAIL" : "PASS";
|
||||||
|
},
|
||||||
|
};
|
||||||
|
console.log(function(a) {
|
||||||
|
return a;
|
||||||
|
}(o.f)());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
f: function() {
|
||||||
|
return this === o ? "FAIL" : "PASS";
|
||||||
|
},
|
||||||
|
};
|
||||||
|
console.log((0, o.f)());
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
preserve_binding_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
f: function() {
|
||||||
|
return this === o ? "FAIL" : "PASS";
|
||||||
|
},
|
||||||
|
};
|
||||||
|
console.log(function(a) {
|
||||||
|
return a;
|
||||||
|
}(o.f)());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
f: function() {
|
||||||
|
return this === o ? "FAIL" : "PASS";
|
||||||
|
},
|
||||||
|
};
|
||||||
|
console.log((0, o.f)());
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
function f(x) {
|
function f(x) {
|
||||||
return g(x);
|
return g(x);
|
||||||
function g(x) {
|
function g(x) {
|
||||||
return x;
|
return x + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -674,7 +674,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
var command = uglifyjscmd + " test/input/rename/input.js --rename";
|
var command = uglifyjscmd + " test/input/rename/input.js --rename";
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(stdout, "function f(a){return b(a);function b(c){return c}}\n");
|
assert.strictEqual(stdout, "function f(a){return b(a);function b(c){return c+1}}\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -682,7 +682,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
var command = uglifyjscmd + " test/input/rename/input.js -mc passes=2 --no-rename";
|
var command = uglifyjscmd + " test/input/rename/input.js -mc passes=2 --no-rename";
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(stdout, "function f(n){return function(n){return n}(n)}\n");
|
assert.strictEqual(stdout, "function f(n){return function(n){return n+1}(n)}\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -690,7 +690,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
var command = uglifyjscmd + " test/input/rename/input.js -mc passes=2";
|
var command = uglifyjscmd + " test/input/rename/input.js -mc passes=2";
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(stdout, "function f(n){return n}\n");
|
assert.strictEqual(stdout, "function f(n){return n+1}\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -698,7 +698,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
var command = uglifyjscmd + " test/input/rename/input.js -c passes=2";
|
var command = uglifyjscmd + " test/input/rename/input.js -c passes=2";
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(stdout, "function f(x){return function(x){return x}(x)}\n");
|
assert.strictEqual(stdout, "function f(x){return function(x){return x+1}(x)}\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -704,6 +704,7 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
VAR_NAMES.length = nameLenBefore;
|
VAR_NAMES.length = nameLenBefore;
|
||||||
|
if (canThrow && rng(8) == 0 && !/^new /.test(s[0])) s[s.length - 1] += "()";
|
||||||
return filterDirective(s).join("\n");
|
return filterDirective(s).join("\n");
|
||||||
case p++:
|
case p++:
|
||||||
case p++:
|
case p++:
|
||||||
|
|||||||
Reference in New Issue
Block a user