@@ -2997,10 +2997,10 @@ merge(Compressor.prototype, {
|
||||
return self;
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("make_var_name", function(prefix) {
|
||||
var var_names = this.var_names;
|
||||
AST_Scope.DEFMETHOD("var_names", function() {
|
||||
var var_names = this._var_names;
|
||||
if (!var_names) {
|
||||
this.var_names = var_names = Object.create(null);
|
||||
this._var_names = var_names = Object.create(null);
|
||||
this.enclosed.forEach(function(def) {
|
||||
var_names[def.name] = true;
|
||||
});
|
||||
@@ -3008,6 +3008,11 @@ merge(Compressor.prototype, {
|
||||
var_names[name] = true;
|
||||
});
|
||||
}
|
||||
return var_names;
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("make_var_name", function(prefix) {
|
||||
var var_names = this.var_names();
|
||||
prefix = prefix.replace(/[^a-z_$]+/ig, "_");
|
||||
var name = prefix;
|
||||
for (var i = 0; var_names[name]; i++) name = prefix + "$" + i;
|
||||
@@ -3862,7 +3867,7 @@ merge(Compressor.prototype, {
|
||||
}
|
||||
}
|
||||
if (fn instanceof AST_Function) {
|
||||
var def;
|
||||
var def, scope, value;
|
||||
if (compressor.option("inline")
|
||||
&& !fn.uses_arguments
|
||||
&& !fn.uses_eval
|
||||
@@ -3871,24 +3876,13 @@ merge(Compressor.prototype, {
|
||||
: compressor.option("unused")
|
||||
&& (def = exp.definition()).references.length == 1
|
||||
&& !recursive_ref(compressor, def))
|
||||
&& !self.has_pure_annotation(compressor)
|
||||
&& !fn.contains_this()
|
||||
&& all(fn.argnames, function(arg) {
|
||||
return arg.__unused;
|
||||
})
|
||||
&& !self.has_pure_annotation(compressor)) {
|
||||
var value;
|
||||
if (stat instanceof AST_Return) {
|
||||
value = stat.value;
|
||||
} else if (stat instanceof AST_SimpleStatement) {
|
||||
value = make_node(AST_UnaryPrefix, stat, {
|
||||
operator: "void",
|
||||
expression: stat.body
|
||||
});
|
||||
}
|
||||
if (value) {
|
||||
var args = self.args.concat(value);
|
||||
return make_sequence(self, args).optimize(compressor);
|
||||
}
|
||||
&& (scope = can_flatten_args(fn))
|
||||
&& (value = flatten_body(stat))) {
|
||||
var expressions = flatten_args(fn, scope);
|
||||
expressions.push(value);
|
||||
return make_sequence(self, expressions).optimize(compressor);
|
||||
}
|
||||
if (compressor.option("side_effects") && all(fn.body, is_empty)) {
|
||||
var args = self.args.concat(make_node(AST_Undefined, self));
|
||||
@@ -3917,6 +3911,62 @@ merge(Compressor.prototype, {
|
||||
return best_of(compressor, ev, self);
|
||||
}
|
||||
return self;
|
||||
|
||||
function can_flatten_args(fn) {
|
||||
var scope = compressor.find_parent(AST_Scope);
|
||||
var safe_to_inject = compressor.toplevel.vars || !(scope instanceof AST_Toplevel);
|
||||
return all(fn.argnames, function(arg) {
|
||||
return arg.__unused || safe_to_inject && !scope.var_names()[arg.name];
|
||||
}) && scope;
|
||||
}
|
||||
|
||||
function flatten_args(fn, scope) {
|
||||
var decls = [];
|
||||
var expressions = [];
|
||||
for (var len = fn.argnames.length, i = len; --i >= 0;) {
|
||||
var name = fn.argnames[i];
|
||||
var value = self.args[i];
|
||||
if (name.__unused) {
|
||||
if (value || expressions.length) {
|
||||
expressions.unshift(value || make_node(AST_Undefined, self));
|
||||
}
|
||||
} else {
|
||||
decls.unshift(make_node(AST_VarDef, name, {
|
||||
name: name,
|
||||
value: null
|
||||
}));
|
||||
var sym = make_node(AST_SymbolRef, name, name);
|
||||
name.definition().references.push(sym);
|
||||
expressions.unshift(make_node(AST_Assign, self, {
|
||||
operator: "=",
|
||||
left: sym,
|
||||
right: value || make_node(AST_Undefined, self)
|
||||
}));
|
||||
}
|
||||
}
|
||||
for (i = len, len = self.args.length; i < len; i++) {
|
||||
expressions.push(self.args[i]);
|
||||
}
|
||||
if (decls.length) {
|
||||
for (i = 0; compressor.parent(i) !== scope;) i++;
|
||||
i = scope.body.indexOf(compressor.parent(i - 1)) + 1;
|
||||
scope.body.splice(i, 0, make_node(AST_Var, fn, {
|
||||
definitions: decls
|
||||
}));
|
||||
}
|
||||
return expressions;
|
||||
}
|
||||
|
||||
function flatten_body(stat) {
|
||||
if (stat instanceof AST_Return) {
|
||||
return stat.value;
|
||||
} else if (stat instanceof AST_SimpleStatement) {
|
||||
return make_node(AST_UnaryPrefix, stat, {
|
||||
operator: "void",
|
||||
expression: stat.body
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
OPT(AST_New, function(self, compressor){
|
||||
|
||||
Reference in New Issue
Block a user