inline functions with AST_Var
This commit is contained in:
parent
6dead95eb3
commit
2a9934e485
152
lib/compress.js
152
lib/compress.js
|
|
@ -4030,7 +4030,7 @@ merge(Compressor.prototype, {
|
||||||
if (compressor.option("inline")
|
if (compressor.option("inline")
|
||||||
&& !fn.uses_arguments
|
&& !fn.uses_arguments
|
||||||
&& !fn.uses_eval
|
&& !fn.uses_eval
|
||||||
&& fn.body.length == 1
|
&& can_flatten_body()
|
||||||
&& (exp === fn ? !fn.name
|
&& (exp === fn ? !fn.name
|
||||||
: compressor.option("unused")
|
: compressor.option("unused")
|
||||||
&& (def = exp.definition()).references.length == 1
|
&& (def = exp.definition()).references.length == 1
|
||||||
|
|
@ -4038,11 +4038,9 @@ merge(Compressor.prototype, {
|
||||||
&& fn.is_constant_expression(exp.scope))
|
&& fn.is_constant_expression(exp.scope))
|
||||||
&& !self.pure
|
&& !self.pure
|
||||||
&& !fn.contains_this()
|
&& !fn.contains_this()
|
||||||
&& can_flatten_args(fn)
|
&& can_inject_symbols()
|
||||||
&& (value = flatten_body(stat))) {
|
&& (value = return_value(stat))) {
|
||||||
var expressions = flatten_args(fn);
|
return make_sequence(self, flatten_fn()).optimize(compressor);
|
||||||
expressions.push(value.clone(true));
|
|
||||||
return make_sequence(self, expressions).optimize(compressor);
|
|
||||||
}
|
}
|
||||||
if (compressor.option("side_effects") && all(fn.body, is_empty)) {
|
if (compressor.option("side_effects") && all(fn.body, is_empty)) {
|
||||||
var args = self.args.concat(make_node(AST_Undefined, self));
|
var args = self.args.concat(make_node(AST_Undefined, self));
|
||||||
|
|
@ -4072,7 +4070,64 @@ merge(Compressor.prototype, {
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
|
|
||||||
function can_flatten_args(fn) {
|
function can_flatten_body() {
|
||||||
|
var len = fn.body.length;
|
||||||
|
if (len == 1) return true;
|
||||||
|
stat = null;
|
||||||
|
for (var i = 0; i < len; i++) {
|
||||||
|
var line = fn.body[i];
|
||||||
|
if (line instanceof AST_Definitions) {
|
||||||
|
if (stat && !all(line.definitions, function(var_def) {
|
||||||
|
return !var_def.value;
|
||||||
|
})) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (stat) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
stat = line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
function can_inject_args(catches, defs, safe_to_inject) {
|
||||||
|
for (var i = 0, len = fn.argnames.length; i < len; i++) {
|
||||||
|
var arg = fn.argnames[i];
|
||||||
|
if (arg.__unused) continue;
|
||||||
|
if (!safe_to_inject
|
||||||
|
|| catches[arg.name]
|
||||||
|
|| identifier_atom(arg.name)
|
||||||
|
|| scope.var_names()[arg.name]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (in_loop) in_loop.push(arg.definition());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function can_inject_vars(catches, defs, safe_to_inject) {
|
||||||
|
var len = fn.body.length;
|
||||||
|
if (len == 1) return true;
|
||||||
|
if (!safe_to_inject) return false;
|
||||||
|
for (var i = 0; i < len; i++) {
|
||||||
|
var stat = fn.body[i];
|
||||||
|
if (stat instanceof AST_Definitions) {
|
||||||
|
for (var j = stat.definitions.length; --j >= 0;) {
|
||||||
|
var name = stat.definitions[j].name;
|
||||||
|
if (catches[name.name]
|
||||||
|
|| identifier_atom(name.name)
|
||||||
|
|| scope.var_names()[name.name]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (defs) defs.push(name.definition());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function can_inject_symbols() {
|
||||||
var catches = Object.create(null);
|
var catches = Object.create(null);
|
||||||
do {
|
do {
|
||||||
scope = compressor.parent(++level);
|
scope = compressor.parent(++level);
|
||||||
|
|
@ -4085,54 +4140,67 @@ merge(Compressor.prototype, {
|
||||||
}
|
}
|
||||||
} while (!(scope instanceof AST_Scope));
|
} while (!(scope instanceof AST_Scope));
|
||||||
var safe_to_inject = compressor.toplevel.vars || !(scope instanceof AST_Toplevel);
|
var safe_to_inject = compressor.toplevel.vars || !(scope instanceof AST_Toplevel);
|
||||||
for (var i = 0, len = fn.argnames.length; i < len; i++) {
|
if (!can_inject_vars(catches, in_loop, safe_to_inject)) return false;
|
||||||
var arg = fn.argnames[i];
|
if (!can_inject_args(catches, in_loop, safe_to_inject)) return false;
|
||||||
if (arg.__unused) continue;
|
return !in_loop || in_loop.length == 0 || !is_reachable(fn, in_loop);
|
||||||
if (!safe_to_inject
|
|
||||||
|| catches[arg.name]
|
|
||||||
|| identifier_atom(arg.name)
|
|
||||||
|| scope.var_names()[arg.name]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (in_loop) in_loop.push(arg.definition());
|
|
||||||
}
|
|
||||||
return !in_loop || in_loop.length == 0 || !is_reachable(stat, in_loop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function flatten_args(fn) {
|
function append_var(decls, expressions, name, value) {
|
||||||
var decls = [];
|
var def = name.definition();
|
||||||
var expressions = [];
|
scope.var_names()[name.name] = true;
|
||||||
|
scope.variables.set(name.name, def);
|
||||||
|
scope.enclosed.push(def);
|
||||||
|
decls.push(make_node(AST_VarDef, name, {
|
||||||
|
name: name,
|
||||||
|
value: null
|
||||||
|
}));
|
||||||
|
var sym = make_node(AST_SymbolRef, name, name);
|
||||||
|
def.references.push(sym);
|
||||||
|
if (value) expressions.push(make_node(AST_Assign, self, {
|
||||||
|
operator: "=",
|
||||||
|
left: sym,
|
||||||
|
right: value
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function flatten_args(decls, expressions) {
|
||||||
for (var len = fn.argnames.length, i = len; --i >= 0;) {
|
for (var len = fn.argnames.length, i = len; --i >= 0;) {
|
||||||
var name = fn.argnames[i];
|
var name = fn.argnames[i];
|
||||||
var value = self.args[i];
|
var value = self.args[i];
|
||||||
if (name.__unused || scope.var_names()[name.name]) {
|
if (name.__unused || scope.var_names()[name.name]) {
|
||||||
if (value) {
|
if (value) expressions.push(value);
|
||||||
expressions.unshift(value);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
var def = name.definition();
|
|
||||||
scope.var_names()[name.name] = true;
|
|
||||||
scope.variables.set(name.name, def);
|
|
||||||
scope.enclosed.push(def);
|
|
||||||
var symbol = make_node(AST_SymbolVar, name, name);
|
var symbol = make_node(AST_SymbolVar, name, name);
|
||||||
def.orig.push(symbol);
|
name.definition().orig.push(symbol);
|
||||||
decls.unshift(make_node(AST_VarDef, name, {
|
|
||||||
name: symbol,
|
|
||||||
value: null
|
|
||||||
}));
|
|
||||||
var sym = make_node(AST_SymbolRef, name, name);
|
|
||||||
def.references.push(sym);
|
|
||||||
if (!value && in_loop) value = make_node(AST_Undefined, self);
|
if (!value && in_loop) value = make_node(AST_Undefined, self);
|
||||||
if (value) expressions.unshift(make_node(AST_Assign, self, {
|
append_var(decls, expressions, symbol, value);
|
||||||
operator: "=",
|
|
||||||
left: sym,
|
|
||||||
right: value
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
decls.reverse();
|
||||||
|
expressions.reverse();
|
||||||
for (i = len, len = self.args.length; i < len; i++) {
|
for (i = len, len = self.args.length; i < len; i++) {
|
||||||
expressions.push(self.args[i]);
|
expressions.push(self.args[i]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function flatten_body(decls, expressions) {
|
||||||
|
for (i = 0, len = fn.body.length; i < len; i++) {
|
||||||
|
var stat = fn.body[i];
|
||||||
|
if (stat instanceof AST_Definitions) {
|
||||||
|
stat.definitions.forEach(function(var_def) {
|
||||||
|
append_var(decls, expressions, var_def.name, var_def.value);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
expressions.push(value.clone(true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function flatten_fn() {
|
||||||
|
var decls = [];
|
||||||
|
var expressions = [];
|
||||||
|
flatten_args(decls, expressions);
|
||||||
|
flatten_body(decls, expressions);
|
||||||
if (decls.length) {
|
if (decls.length) {
|
||||||
i = scope.body.indexOf(compressor.parent(level - 1)) + 1;
|
i = scope.body.indexOf(compressor.parent(level - 1)) + 1;
|
||||||
scope.body.splice(i, 0, make_node(AST_Var, fn, {
|
scope.body.splice(i, 0, make_node(AST_Var, fn, {
|
||||||
|
|
@ -4142,7 +4210,7 @@ merge(Compressor.prototype, {
|
||||||
return expressions;
|
return expressions;
|
||||||
}
|
}
|
||||||
|
|
||||||
function flatten_body(stat) {
|
function return_value(stat) {
|
||||||
if (stat instanceof AST_Return) {
|
if (stat instanceof AST_Return) {
|
||||||
return stat.value;
|
return stat.value;
|
||||||
} else if (stat instanceof AST_SimpleStatement) {
|
} else if (stat instanceof AST_SimpleStatement) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user