@@ -2997,10 +2997,10 @@ merge(Compressor.prototype, {
|
|||||||
return self;
|
return self;
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("make_var_name", function(prefix) {
|
AST_Scope.DEFMETHOD("var_names", function() {
|
||||||
var var_names = this.var_names;
|
var var_names = this._var_names;
|
||||||
if (!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) {
|
this.enclosed.forEach(function(def) {
|
||||||
var_names[def.name] = true;
|
var_names[def.name] = true;
|
||||||
});
|
});
|
||||||
@@ -3008,6 +3008,11 @@ merge(Compressor.prototype, {
|
|||||||
var_names[name] = true;
|
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, "_");
|
prefix = prefix.replace(/[^a-z_$]+/ig, "_");
|
||||||
var name = prefix;
|
var name = prefix;
|
||||||
for (var i = 0; var_names[name]; i++) name = prefix + "$" + i;
|
for (var i = 0; var_names[name]; i++) name = prefix + "$" + i;
|
||||||
@@ -3862,7 +3867,7 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fn instanceof AST_Function) {
|
if (fn instanceof AST_Function) {
|
||||||
var def;
|
var def, scope, value;
|
||||||
if (compressor.option("inline")
|
if (compressor.option("inline")
|
||||||
&& !fn.uses_arguments
|
&& !fn.uses_arguments
|
||||||
&& !fn.uses_eval
|
&& !fn.uses_eval
|
||||||
@@ -3871,24 +3876,13 @@ merge(Compressor.prototype, {
|
|||||||
: compressor.option("unused")
|
: compressor.option("unused")
|
||||||
&& (def = exp.definition()).references.length == 1
|
&& (def = exp.definition()).references.length == 1
|
||||||
&& !recursive_ref(compressor, def))
|
&& !recursive_ref(compressor, def))
|
||||||
|
&& !self.has_pure_annotation(compressor)
|
||||||
&& !fn.contains_this()
|
&& !fn.contains_this()
|
||||||
&& all(fn.argnames, function(arg) {
|
&& (scope = can_flatten_args(fn))
|
||||||
return arg.__unused;
|
&& (value = flatten_body(stat))) {
|
||||||
})
|
var expressions = flatten_args(fn, scope);
|
||||||
&& !self.has_pure_annotation(compressor)) {
|
expressions.push(value);
|
||||||
var value;
|
return make_sequence(self, expressions).optimize(compressor);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
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));
|
||||||
@@ -3917,6 +3911,62 @@ merge(Compressor.prototype, {
|
|||||||
return best_of(compressor, ev, self);
|
return best_of(compressor, ev, self);
|
||||||
}
|
}
|
||||||
return 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){
|
OPT(AST_New, function(self, compressor){
|
||||||
|
|||||||
@@ -3317,15 +3317,14 @@ issue_2436_4: {
|
|||||||
}(o));
|
}(o));
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(function(c) {
|
console.log({
|
||||||
return {
|
x: (c = {
|
||||||
x: c.a,
|
|
||||||
y: c.b,
|
|
||||||
};
|
|
||||||
}({
|
|
||||||
a: 1,
|
a: 1,
|
||||||
b: 2,
|
b: 2,
|
||||||
}));
|
}).a,
|
||||||
|
y: c.b,
|
||||||
|
});
|
||||||
|
var c;
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
@@ -3448,12 +3447,11 @@ issue_2436_8: {
|
|||||||
}(o));
|
}(o));
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(function(c) {
|
console.log({
|
||||||
return {
|
x: (c = o).a,
|
||||||
x: c.a,
|
|
||||||
y: c.b,
|
y: c.b,
|
||||||
};
|
});
|
||||||
}(o));
|
var c;
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
@@ -3478,12 +3476,11 @@ issue_2436_9: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var o = console;
|
var o = console;
|
||||||
console.log(function(c) {
|
console.log({
|
||||||
return {
|
x: (c = o).a,
|
||||||
x: c.a,
|
|
||||||
y: c.b,
|
y: c.b,
|
||||||
};
|
});
|
||||||
}(o));
|
var c;
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
@@ -3523,13 +3520,12 @@ issue_2436_10: {
|
|||||||
o = { b: 3 };
|
o = { b: 3 };
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
console.log(function(c) {
|
console.log((c = o, [
|
||||||
return [
|
|
||||||
c.a,
|
c.a,
|
||||||
f(c.b),
|
f(c.b),
|
||||||
c.b,
|
c.b,
|
||||||
];
|
]).join(" "));
|
||||||
}(o).join(" "));
|
var c;
|
||||||
}
|
}
|
||||||
expect_stdout: "1 2 2"
|
expect_stdout: "1 2 2"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -578,11 +578,10 @@ issue_2531_1: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function outer() {
|
function outer() {
|
||||||
return function(value) {
|
return value = "Hello", function() {
|
||||||
return function() {
|
|
||||||
return value;
|
return value;
|
||||||
};
|
};
|
||||||
}("Hello");
|
var value;
|
||||||
}
|
}
|
||||||
console.log("Greeting:", outer()());
|
console.log("Greeting:", outer()());
|
||||||
}
|
}
|
||||||
@@ -593,9 +592,10 @@ issue_2531_2: {
|
|||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
inline: true,
|
inline: true,
|
||||||
passes: 2,
|
passes: 3,
|
||||||
reduce_funcs: true,
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -627,9 +627,10 @@ issue_2531_3: {
|
|||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
inline: true,
|
inline: true,
|
||||||
passes: 2,
|
passes: 3,
|
||||||
reduce_funcs: true,
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -747,3 +748,27 @@ inline_loop_4: {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2476: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function foo(x, y, z) {
|
||||||
|
return x < y ? x * y + z : x * z - y;
|
||||||
|
}
|
||||||
|
for (var sum = 0, i = 0; i < 10; i++)
|
||||||
|
sum += foo(i, i + 1, 3 * i);
|
||||||
|
console.log(sum);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
for (var sum = 0, i = 0; i < 10; i++)
|
||||||
|
sum += (x = i, y = i + 1, z = 3 * i, x < y ? x * y + z : x * z - y);
|
||||||
|
var x, y, z;
|
||||||
|
console.log(sum);
|
||||||
|
}
|
||||||
|
expect_stdout: "465"
|
||||||
|
}
|
||||||
|
|||||||
@@ -55,9 +55,8 @@ issue_2377_2: {
|
|||||||
console.log(obj.foo, obj.cube(3));
|
console.log(obj.foo, obj.cube(3));
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(1, function(x) {
|
console.log(1, (x = 3, x * x * x));
|
||||||
return x * x * x;
|
var x;
|
||||||
}(3));
|
|
||||||
}
|
}
|
||||||
expect_stdout: "1 27"
|
expect_stdout: "1 27"
|
||||||
}
|
}
|
||||||
@@ -67,9 +66,10 @@ issue_2377_3: {
|
|||||||
evaluate: true,
|
evaluate: true,
|
||||||
inline: true,
|
inline: true,
|
||||||
hoist_props: true,
|
hoist_props: true,
|
||||||
passes: 3,
|
passes: 4,
|
||||||
reduce_funcs: true,
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1396,7 +1396,7 @@ defun_inline_3: {
|
|||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
inline: true,
|
inline: true,
|
||||||
passes: 2,
|
passes: 3,
|
||||||
reduce_funcs: true,
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -2250,12 +2250,11 @@ redefine_farg_2: {
|
|||||||
console.log(f([]), g([]), h([]));
|
console.log(f([]), g([]), h([]));
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(function(a) {
|
console.log((a = [], typeof a), "number",function(a, b) {
|
||||||
return typeof a;
|
|
||||||
}([]), "number",function(a, b) {
|
|
||||||
a = b;
|
a = b;
|
||||||
return typeof a;
|
return typeof a;
|
||||||
}([]));
|
}([]));
|
||||||
|
var a;
|
||||||
}
|
}
|
||||||
expect_stdout: "object number undefined"
|
expect_stdout: "object number undefined"
|
||||||
}
|
}
|
||||||
@@ -2266,7 +2265,7 @@ redefine_farg_3: {
|
|||||||
evaluate: true,
|
evaluate: true,
|
||||||
inline: true,
|
inline: true,
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
passes: 2,
|
passes: 3,
|
||||||
reduce_funcs: true,
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
@@ -3107,6 +3106,7 @@ obj_var_2: {
|
|||||||
|
|
||||||
obj_arg_1: {
|
obj_arg_1: {
|
||||||
options = {
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
inline: true,
|
inline: true,
|
||||||
passes: 2,
|
passes: 2,
|
||||||
@@ -3138,9 +3138,10 @@ obj_arg_1: {
|
|||||||
|
|
||||||
obj_arg_2: {
|
obj_arg_2: {
|
||||||
options = {
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
inline: true,
|
inline: true,
|
||||||
passes: 2,
|
passes: 3,
|
||||||
properties: true,
|
properties: true,
|
||||||
reduce_funcs: true,
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ describe("bin/uglifyjs with input file globs", function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("bin/uglifyjs with multiple input file globs.", function(done) {
|
it("bin/uglifyjs with multiple input file globs.", function(done) {
|
||||||
var command = uglifyjscmd + ' "test/input/issue-1242/???.es5" "test/input/issue-1242/*.js" -mc toplevel,passes=2';
|
var command = uglifyjscmd + ' "test/input/issue-1242/???.es5" "test/input/issue-1242/*.js" -mc toplevel,passes=3';
|
||||||
|
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|||||||
Reference in New Issue
Block a user