Compare commits

...

9 Commits

Author SHA1 Message Date
Alex Lam S.L
ea999b0e92 v3.4.9 2018-08-31 04:28:21 +00:00
Alex Lam S.L
ce7e220de4 fix corner case in conditionals (#3244) 2018-08-30 15:59:05 +08:00
Alex Lam S.L
2bdaca10ae enhance conditionals (#3243) 2018-08-30 01:06:34 +08:00
Alex Lam S.L
aa0029204e fix corner case in reduce_vars (#3241)
fixes #3240
2018-08-29 22:14:25 +08:00
Alex Lam S.L
f352bcec3a fix corner case in collapse_vars (#3239)
fixes #3238
2018-08-29 11:34:34 +08:00
Alex Lam S.L
08514030f4 v3.4.8 2018-08-23 15:27:34 +08:00
Alex Lam S.L
694ca5d045 fix corner case in unused (#3234)
fixes #3233
2018-08-23 06:03:39 +08:00
Alex Lam S.L
57fb58b263 enhance if_return (#3232) 2018-08-21 18:34:16 +08:00
alexlamsl
18c1c9b38a update dependencies
- commander@2.17.1
2018-08-14 17:06:09 +08:00
8 changed files with 750 additions and 119 deletions

View File

@@ -450,8 +450,7 @@ merge(Compressor.prototype, {
return value instanceof AST_Node && def.fixed.parent_scope === scope;
}
return all(def.orig, function(sym) {
return !(sym instanceof AST_SymbolDefun
|| sym instanceof AST_SymbolLambda);
return !(sym instanceof AST_SymbolDefun || sym instanceof AST_SymbolLambda);
});
}
@@ -1482,14 +1481,26 @@ merge(Compressor.prototype, {
}
function get_rhs(expr) {
if (!(candidate instanceof AST_Assign && candidate.operator == "=")) return;
return candidate.right;
return candidate instanceof AST_Assign && candidate.operator == "=" && candidate.right;
}
function get_rvalue(expr) {
return expr[expr instanceof AST_Assign ? "right" : "value"];
}
function invariant(expr) {
if (expr instanceof AST_Array) return false;
if (expr instanceof AST_Binary && lazy_op[expr.operator]) {
return invariant(expr.left) && invariant(expr.right);
}
if (expr instanceof AST_Call) return false;
if (expr instanceof AST_Conditional) {
return invariant(expr.consequent) && invariant(expr.alternative);
}
if (expr instanceof AST_Object) return false;
return !expr.has_side_effects(compressor);
}
function foldable(expr) {
if (expr instanceof AST_SymbolRef) {
var value = expr.evaluate(compressor);
@@ -1502,7 +1513,7 @@ merge(Compressor.prototype, {
return rhs_fuzzy_match(expr.evaluate(compressor), rhs_exact_match);
}
if (!(lhs instanceof AST_SymbolRef)) return false;
if (expr.has_side_effects(compressor)) return false;
if (!invariant(expr)) return false;
var circular;
var def = lhs.definition();
expr.walk(new TreeWalker(function(node) {
@@ -1699,6 +1710,19 @@ merge(Compressor.prototype, {
continue;
}
if (ab && !stat.alternative && stat.body instanceof AST_BlockStatement && next instanceof AST_Jump) {
var negated = stat.condition.negate(compressor);
if (negated.print_to_string().length <= stat.condition.print_to_string().length) {
CHANGED = true;
stat = stat.clone();
stat.condition = negated;
statements[j] = stat.body;
stat.body = next;
statements[i] = stat.transform(compressor);
continue;
}
}
var ab = aborts(stat.alternative);
if (can_merge_flow(ab)) {
if (ab.label) {
@@ -2968,19 +2992,21 @@ merge(Compressor.prototype, {
// determine if expression has side effects
(function(def) {
def(AST_Node, return_true);
def(AST_EmptyStatement, return_false);
def(AST_Constant, return_false);
def(AST_This, return_false);
function any(list, compressor) {
for (var i = list.length; --i >= 0;)
if (list[i].has_side_effects(compressor))
return true;
return false;
}
def(AST_Node, return_true);
def(AST_Array, function(compressor) {
return any(this.elements, compressor);
});
def(AST_Assign, return_true);
def(AST_Binary, function(compressor) {
return this.left.has_side_effects(compressor)
|| this.right.has_side_effects(compressor);
});
def(AST_Block, function(compressor) {
return any(this.body, compressor);
});
@@ -2992,19 +3018,24 @@ merge(Compressor.prototype, {
}
return any(this.args, compressor);
});
def(AST_Switch, function(compressor) {
return this.expression.has_side_effects(compressor)
|| any(this.body, compressor);
});
def(AST_Case, function(compressor) {
return this.expression.has_side_effects(compressor)
|| any(this.body, compressor);
});
def(AST_Try, function(compressor) {
return any(this.body, compressor)
|| this.bcatch && this.bcatch.has_side_effects(compressor)
|| this.bfinally && this.bfinally.has_side_effects(compressor);
def(AST_Conditional, function(compressor) {
return this.condition.has_side_effects(compressor)
|| this.consequent.has_side_effects(compressor)
|| this.alternative.has_side_effects(compressor);
});
def(AST_Constant, return_false);
def(AST_Definitions, function(compressor) {
return any(this.definitions, compressor);
});
def(AST_Dot, function(compressor) {
return this.expression.may_throw_on_access(compressor)
|| this.expression.has_side_effects(compressor);
});
def(AST_EmptyStatement, return_false);
def(AST_If, function(compressor) {
return this.condition.has_side_effects(compressor)
|| this.body && this.body.has_side_effects(compressor)
@@ -3013,41 +3044,13 @@ merge(Compressor.prototype, {
def(AST_LabeledStatement, function(compressor) {
return this.body.has_side_effects(compressor);
});
def(AST_SimpleStatement, function(compressor) {
return this.body.has_side_effects(compressor);
});
def(AST_Lambda, return_false);
def(AST_Binary, function(compressor) {
return this.left.has_side_effects(compressor)
|| this.right.has_side_effects(compressor);
});
def(AST_Assign, return_true);
def(AST_Conditional, function(compressor) {
return this.condition.has_side_effects(compressor)
|| this.consequent.has_side_effects(compressor)
|| this.alternative.has_side_effects(compressor);
});
def(AST_Unary, function(compressor) {
return unary_side_effects[this.operator]
|| this.expression.has_side_effects(compressor);
});
def(AST_SymbolRef, function(compressor) {
return !this.is_declared(compressor);
});
def(AST_SymbolDeclaration, return_false);
def(AST_Object, function(compressor) {
return any(this.properties, compressor);
});
def(AST_ObjectProperty, function(compressor) {
return this.value.has_side_effects(compressor);
});
def(AST_Array, function(compressor) {
return any(this.elements, compressor);
});
def(AST_Dot, function(compressor) {
return this.expression.may_throw_on_access(compressor)
|| this.expression.has_side_effects(compressor);
});
def(AST_Sub, function(compressor) {
return this.expression.may_throw_on_access(compressor)
|| this.expression.has_side_effects(compressor)
@@ -3056,8 +3059,26 @@ merge(Compressor.prototype, {
def(AST_Sequence, function(compressor) {
return any(this.expressions, compressor);
});
def(AST_Definitions, function(compressor) {
return any(this.definitions, compressor);
def(AST_SimpleStatement, function(compressor) {
return this.body.has_side_effects(compressor);
});
def(AST_Switch, function(compressor) {
return this.expression.has_side_effects(compressor)
|| any(this.body, compressor);
});
def(AST_SymbolDeclaration, return_false);
def(AST_SymbolRef, function(compressor) {
return !this.is_declared(compressor);
});
def(AST_This, return_false);
def(AST_Try, function(compressor) {
return any(this.body, compressor)
|| this.bcatch && this.bcatch.has_side_effects(compressor)
|| this.bfinally && this.bfinally.has_side_effects(compressor);
});
def(AST_Unary, function(compressor) {
return unary_side_effects[this.operator]
|| this.expression.has_side_effects(compressor);
});
def(AST_VarDef, function(compressor) {
return this.value;
@@ -3316,13 +3337,14 @@ merge(Compressor.prototype, {
} else if (node instanceof AST_Unary && node.write_only) {
sym = node.expression;
}
if (/strict/.test(compressor.option("pure_getters"))) {
if (!/strict/.test(compressor.option("pure_getters"))) return sym instanceof AST_SymbolRef && sym;
while (sym instanceof AST_PropAccess && !sym.expression.may_throw_on_access(compressor)) {
if (sym instanceof AST_Sub) props.unshift(sym.property);
sym = sym.expression;
}
}
return sym;
return sym instanceof AST_SymbolRef && all(sym.definition().orig, function(sym) {
return !(sym instanceof AST_SymbolLambda);
}) && sym;
};
var in_use = [];
var in_use_ids = Object.create(null); // avoid expensive linear scans of in_use
@@ -3417,7 +3439,7 @@ merge(Compressor.prototype, {
var parent = tt.parent();
if (drop_vars) {
var props = [], sym = assign_as_unused(node, props);
if (sym instanceof AST_SymbolRef) {
if (sym) {
var def = sym.definition();
var in_use = def.id in in_use_ids;
var value = null;
@@ -3616,8 +3638,7 @@ merge(Compressor.prototype, {
function scan_ref_scoped(node, descend) {
var node_def, props = [], sym = assign_as_unused(node, props);
if (sym instanceof AST_SymbolRef
&& self.variables.get(sym.name) === (node_def = sym.definition())) {
if (sym && self.variables.get(sym.name) === (node_def = sym.definition())) {
props.forEach(function(prop) {
prop.walk(tw);
});
@@ -5730,38 +5751,34 @@ merge(Compressor.prototype, {
}
var parent = compressor.parent();
if (compressor.option("reduce_vars") && is_lhs(self, parent) !== self) {
var d = self.definition();
var def = self.definition();
var fixed = self.fixed_value();
var single_use = d.single_use
&& !(parent instanceof AST_Call && parent.is_expr_pure(compressor));
var single_use = def.single_use && !(parent instanceof AST_Call && parent.is_expr_pure(compressor));
if (single_use && fixed instanceof AST_Lambda) {
if (d.scope !== self.scope
&& (!compressor.option("reduce_funcs")
|| d.escaped == 1
|| fixed.inlined)) {
if (def.scope !== self.scope
&& (!compressor.option("reduce_funcs") || def.escaped == 1 || fixed.inlined)) {
single_use = false;
} else if (recursive_ref(compressor, d)) {
} else if (recursive_ref(compressor, def)) {
single_use = false;
} else if (d.scope !== self.scope || d.orig[0] instanceof AST_SymbolFunarg) {
} else if (def.scope !== self.scope || def.orig[0] instanceof AST_SymbolFunarg) {
single_use = fixed.is_constant_expression(self.scope);
if (single_use == "f") {
var scope = self.scope;
do {
if (scope instanceof AST_Defun || scope instanceof AST_Function) {
do if (scope instanceof AST_Defun || scope instanceof AST_Function) {
scope.inlined = true;
}
} while (scope = scope.parent_scope);
}
}
}
if (single_use && fixed) {
def.single_use = false;
if (fixed instanceof AST_Defun) {
fixed._squeezed = true;
fixed = make_node(AST_Function, fixed, fixed);
fixed.name = make_node(AST_SymbolLambda, fixed.name, fixed.name);
}
var value;
if (d.recursive_refs > 0) {
if (def.recursive_refs > 0) {
value = fixed.clone(true);
var defun_def = value.name.definition();
var lambda_def = value.variables.get(value.name.name);
@@ -5773,9 +5790,13 @@ merge(Compressor.prototype, {
lambda_def = value.def_function(name);
}
value.walk(new TreeWalker(function(node) {
if (node instanceof AST_SymbolRef && node.definition() === defun_def) {
if (!(node instanceof AST_SymbolRef)) return;
var def = node.definition();
if (def === defun_def) {
node.thedef = lambda_def;
lambda_def.references.push(node);
} else {
def.single_use = false;
}
}));
} else {
@@ -5784,12 +5805,11 @@ merge(Compressor.prototype, {
}
return value;
}
if (fixed && d.should_replace === undefined) {
if (fixed && def.should_replace === undefined) {
var init;
if (fixed instanceof AST_This) {
if (!(d.orig[0] instanceof AST_SymbolFunarg)
&& all(d.references, function(ref) {
return d.scope === ref.scope;
if (!(def.orig[0] instanceof AST_SymbolFunarg) && all(def.references, function(ref) {
return def.scope === ref.scope;
})) {
init = fixed;
}
@@ -5814,18 +5834,18 @@ merge(Compressor.prototype, {
return result === init || result === fixed ? result.clone(true) : result;
};
}
var name_length = d.name.length;
var name_length = def.name.length;
var overhead = 0;
if (compressor.option("unused") && !compressor.exposed(d)) {
overhead = (name_length + 2 + value_length) / (d.references.length - d.assignments);
if (compressor.option("unused") && !compressor.exposed(def)) {
overhead = (name_length + 2 + value_length) / (def.references.length - def.assignments);
}
d.should_replace = value_length <= name_length + overhead ? fn : false;
def.should_replace = value_length <= name_length + overhead ? fn : false;
} else {
d.should_replace = false;
def.should_replace = false;
}
}
if (d.should_replace) {
return d.should_replace();
if (def.should_replace) {
return def.should_replace();
}
}
return self;
@@ -6027,23 +6047,27 @@ merge(Compressor.prototype, {
// |
// v
// exp = foo ? something : something_else;
if (consequent instanceof AST_Assign
&& alternative instanceof AST_Assign
&& consequent.operator == alternative.operator
&& consequent.left.equivalent_to(alternative.left)
&& (!self.condition.has_side_effects(compressor)
|| consequent.operator == "="
&& !consequent.left.has_side_effects(compressor))) {
var seq_tail = consequent.tail_node();
if (seq_tail instanceof AST_Assign) {
var is_eq = seq_tail.operator == "=";
var alt_tail = is_eq ? alternative.tail_node() : alternative;
if ((is_eq || consequent instanceof AST_Assign)
&& alt_tail instanceof AST_Assign
&& seq_tail.operator == alt_tail.operator
&& seq_tail.left.equivalent_to(alt_tail.left)
&& (!condition.has_side_effects(compressor)
|| is_eq && !seq_tail.left.has_side_effects(compressor))) {
return make_node(AST_Assign, self, {
operator: consequent.operator,
left: consequent.left,
operator: seq_tail.operator,
left: seq_tail.left,
right: make_node(AST_Conditional, self, {
condition: self.condition,
consequent: consequent.right,
alternative: alternative.right
condition: condition,
consequent: pop_lhs(consequent),
alternative: pop_lhs(alternative)
})
});
}
}
// x ? y(a) : y(b) --> y(x ? a : b)
var arg_index;
if (consequent instanceof AST_Call
@@ -6051,12 +6075,12 @@ merge(Compressor.prototype, {
&& consequent.args.length > 0
&& consequent.args.length == alternative.args.length
&& consequent.expression.equivalent_to(alternative.expression)
&& !self.condition.has_side_effects(compressor)
&& !condition.has_side_effects(compressor)
&& !consequent.expression.has_side_effects(compressor)
&& typeof (arg_index = single_arg_diff()) == "number") {
var node = consequent.clone();
node.args[arg_index] = make_node(AST_Conditional, self, {
condition: self.condition,
condition: condition,
consequent: consequent.args[arg_index],
alternative: alternative.args[arg_index]
});
@@ -6067,7 +6091,7 @@ merge(Compressor.prototype, {
&& consequent.alternative.equivalent_to(alternative)) {
return make_node(AST_Conditional, self, {
condition: make_node(AST_Binary, self, {
left: self.condition,
left: condition,
operator: "&&",
right: consequent.condition
}),
@@ -6078,7 +6102,7 @@ merge(Compressor.prototype, {
// x ? y : y --> x, y
if (consequent.equivalent_to(alternative)) {
return make_sequence(self, [
self.condition,
condition,
consequent
]).optimize(compressor);
}
@@ -6087,7 +6111,7 @@ merge(Compressor.prototype, {
&& consequent.tail_node().equivalent_to(alternative.tail_node())) {
return make_sequence(self, [
make_node(AST_Conditional, self, {
condition: self.condition,
condition: condition,
consequent: pop_seq(consequent),
alternative: pop_seq(alternative)
}),
@@ -6102,7 +6126,7 @@ merge(Compressor.prototype, {
operator: "||",
left: make_node(AST_Binary, self, {
operator: "&&",
left: self.condition,
left: condition,
right: consequent.left
}),
right: alternative
@@ -6112,24 +6136,24 @@ merge(Compressor.prototype, {
if (is_true(self.consequent)) {
if (is_false(self.alternative)) {
// c ? true : false ---> !!c
return booleanize(self.condition);
return booleanize(condition);
}
// c ? true : x ---> !!c || x
return make_node(AST_Binary, self, {
operator: "||",
left: booleanize(self.condition),
left: booleanize(condition),
right: self.alternative
});
}
if (is_false(self.consequent)) {
if (is_true(self.alternative)) {
// c ? false : true ---> !c
return booleanize(self.condition.negate(compressor));
return booleanize(condition.negate(compressor));
}
// c ? false : x ---> !c && x
return make_node(AST_Binary, self, {
operator: "&&",
left: booleanize(self.condition.negate(compressor)),
left: booleanize(condition.negate(compressor)),
right: self.alternative
});
}
@@ -6137,7 +6161,7 @@ merge(Compressor.prototype, {
// c ? x : true ---> !c || x
return make_node(AST_Binary, self, {
operator: "||",
left: booleanize(self.condition.negate(compressor)),
left: booleanize(condition.negate(compressor)),
right: self.consequent
});
}
@@ -6145,7 +6169,7 @@ merge(Compressor.prototype, {
// c ? x : false ---> !!c && x
return make_node(AST_Binary, self, {
operator: "&&",
left: booleanize(self.condition),
left: booleanize(condition),
right: self.consequent
});
}
@@ -6197,6 +6221,13 @@ merge(Compressor.prototype, {
}
}
function pop_lhs(node) {
if (!(node instanceof AST_Sequence)) return node.right;
var exprs = node.expressions.slice();
exprs.push(exprs.pop().right);
return make_sequence(node, exprs);
}
function pop_seq(node) {
if (!(node instanceof AST_Sequence)) return make_node(AST_Number, node, {
value: 0

View File

@@ -3,7 +3,7 @@
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
"license": "BSD-2-Clause",
"version": "3.4.7",
"version": "3.4.9",
"engines": {
"node": ">=0.8.0"
},
@@ -23,7 +23,7 @@
"LICENSE"
],
"dependencies": {
"commander": "~2.16.0",
"commander": "~2.17.1",
"source-map": "~0.6.1"
},
"devDependencies": {

View File

@@ -5827,3 +5827,183 @@ issue_3215_4: {
}
expect_stdout: "number"
}
issue_3238_1: {
options = {
collapse_vars: true,
unsafe: true,
}
input: {
function f(a) {
var b, c;
if (a) {
b = Object.create(null);
c = Object.create(null);
}
return b === c;
}
console.log(f(0), f(1));
}
expect: {
function f(a) {
var b, c;
if (a) {
b = Object.create(null);
c = Object.create(null);
}
return b === c;
}
console.log(f(0), f(1));
}
expect_stdout: "true false"
}
issue_3238_2: {
options = {
collapse_vars: true,
unsafe: true,
}
input: {
function f(a) {
var b, c;
if (a) {
b = Error();
c = Error();
}
return b === c;
}
console.log(f(0), f(1));
}
expect: {
function f(a) {
var b, c;
if (a) {
b = Error();
c = Error();
}
return b === c;
}
console.log(f(0), f(1));
}
expect_stdout: "true false"
}
issue_3238_3: {
options = {
collapse_vars: true,
unsafe: true,
}
input: {
function f(a) {
var b, c;
if (a) {
b = new Date();
c = new Date();
}
return b === c;
}
console.log(f(0), f(1));
}
expect: {
function f(a) {
var b, c;
if (a) {
b = new Date();
c = new Date();
}
return b === c;
}
console.log(f(0), f(1));
}
expect_stdout: "true false"
}
issue_3238_4: {
options = {
collapse_vars: true,
unsafe: true,
}
input: {
function f(a) {
var b, c;
if (a) {
b = a && {};
c = a && {};
}
return b === c;
}
console.log(f(0), f(1));
}
expect: {
function f(a) {
var b, c;
if (a) {
b = a && {};
c = a && {};
}
return b === c;
}
console.log(f(0), f(1));
}
expect_stdout: "true false"
}
issue_3238_5: {
options = {
collapse_vars: true,
unsafe: true,
}
input: {
function f(a) {
var b, c;
if (a) {
b = a ? [] : 42;
c = a ? [] : 42;
}
return b === c;
}
console.log(f(0), f(1));
}
expect: {
function f(a) {
var b, c;
if (a) {
b = a ? [] : 42;
c = a ? [] : 42;
}
return b === c;
}
console.log(f(0), f(1));
}
expect_stdout: "true false"
}
issue_3238_6: {
options = {
collapse_vars: true,
unsafe: true,
}
input: {
function f(a) {
var b, c;
if (a) {
b = a && 0 || [];
c = a && 0 || [];
}
return b === c;
}
console.log(f(0), f(1));
}
expect: {
function f(a) {
var b, c;
if (a) {
b = a && 0 || [];
c = a && 0 || [];
}
return b === c;
}
console.log(f(0), f(1));
}
expect_stdout: "true false"
}

View File

@@ -1292,3 +1292,95 @@ to_and_or: {
}
expect_stdout: true
}
cond_seq_assign_1: {
options = {
conditionals: true,
sequences: true,
}
input: {
function f(a) {
var t;
if (a) {
t = "foo";
t = "bar";
} else {
console.log(t);
t = 42;
}
console.log(t);
}
f(f);
f();
}
expect: {
function f(a) {
var t;
t = a ? (t = "foo", "bar") : (console.log(t), 42),
console.log(t);
}
f(f),
f();
}
expect_stdout: [
"bar",
"undefined",
"42",
]
}
cond_seq_assign_2: {
options = {
conditionals: true,
sequences: true,
}
input: {
function f(a) {
var t;
if (a) {
t = "foo";
a = "bar";
} else {
console.log(t);
t = 42;
}
console.log(t);
}
f(f);
f();
}
expect: {
function f(a) {
var t;
a ? (t = "foo", a = "bar") : (console.log(t), t = 42),
console.log(t);
}
f(f),
f();
}
expect_stdout: [
"foo",
"undefined",
"42",
]
}
cond_seq_assign_3: {
options = {
conditionals: true,
}
input: {
var c = 0;
if (this)
c = 1 + c, c = c + 1;
else
c = 1 + c, c = c + 1;
console.log(c);
}
expect: {
var c = 0;
this, c = 1 + c, c += 1;
console.log(c);
}
expect_stdout: "2"
}

View File

@@ -1982,3 +1982,26 @@ issue_3192: {
"foo bar",
]
}
issue_3233: {
options = {
pure_getters: "strict",
side_effects: true,
unused: true,
}
input: {
var a = function b() {
b.c = "PASS";
};
a();
console.log(a.c);
}
expect: {
var a = function b() {
b.c = "PASS";
};
a();
console.log(a.c);
}
expect_stdout: "PASS"
}

View File

@@ -396,3 +396,151 @@ if_if_return_return: {
}
}
}
if_body_return_1: {
options = {
if_return: true,
}
input: {
var c = "PASS";
function f(a, b) {
if (a) {
if (b) throw new Error(c);
return 42;
}
return true;
}
console.log(f(0, 0));
console.log(f(0, 1));
console.log(f(1, 0));
try {
f(1, 1);
console.log("FAIL");
} catch (e) {
console.log(e.message);
}
}
expect: {
var c = "PASS";
function f(a, b) {
if (a) {
if (b) throw new Error(c);
return 42;
}
return true;
}
console.log(f(0, 0));
console.log(f(0, 1));
console.log(f(1, 0));
try {
f(1, 1);
console.log("FAIL");
} catch (e) {
console.log(e.message);
}
}
expect_stdout: [
"true",
"true",
"42",
"PASS",
]
}
if_body_return_2: {
options = {
if_return: true,
}
input: {
var c = "PASS";
function f(a, b) {
if (0 + a) {
if (b) throw new Error(c);
return 42;
}
return true;
}
console.log(f(0, 0));
console.log(f(0, 1));
console.log(f(1, 0));
try {
f(1, 1);
console.log("FAIL");
} catch (e) {
console.log(e.message);
}
}
expect: {
var c = "PASS";
function f(a, b) {
if (0 + a) {
if (b) throw new Error(c);
return 42;
}
return true;
}
console.log(f(0, 0));
console.log(f(0, 1));
console.log(f(1, 0));
try {
f(1, 1);
console.log("FAIL");
} catch (e) {
console.log(e.message);
}
}
expect_stdout: [
"true",
"true",
"42",
"PASS",
]
}
if_body_return_3: {
options = {
if_return: true,
}
input: {
var c = "PASS";
function f(a, b) {
if (1 == a) {
if (b) throw new Error(c);
return 42;
}
return true;
}
console.log(f(0, 0));
console.log(f(0, 1));
console.log(f(1, 0));
try {
f(1, 1);
console.log("FAIL");
} catch (e) {
console.log(e.message);
}
}
expect: {
var c = "PASS";
function f(a, b) {
if (1 != a) return true;
if (b) throw new Error(c);
return 42;
}
console.log(f(0, 0));
console.log(f(0, 1));
console.log(f(1, 0));
try {
f(1, 1);
console.log("FAIL");
} catch (e) {
console.log(e.message);
}
}
expect_stdout: [
"true",
"true",
"42",
"PASS",
]
}

View File

@@ -5354,6 +5354,7 @@ issue_2774: {
issue_2799_1: {
options = {
passes: 2,
reduce_funcs: true,
reduce_vars: true,
unused: true,
@@ -6429,3 +6430,159 @@ issue_3140_5: {
}
expect_stdout: "1"
}
issue_3240_1: {
options = {
reduce_funcs: true,
reduce_vars: true,
unused: true,
}
input: {
(function() {
f(1);
function f(a) {
console.log(a);
var g = function() {
f(a - 1);
};
if (a) g();
}
})();
}
expect: {
(function() {
(function f(a) {
console.log(a);
var g = function() {
f(a - 1);
};
if (a) g();
})(1);
})();
}
expect_stdout: [
"1",
"0",
]
}
issue_3240_2: {
options = {
passes: 2,
reduce_funcs: true,
reduce_vars: true,
unused: true,
}
input: {
(function() {
f(1);
function f(a) {
console.log(a);
var g = function() {
f(a - 1);
};
if (a) g();
}
})();
}
expect: {
(function() {
(function f(a) {
console.log(a);
if (a) (function() {
f(a - 1);
})();
})(1);
})();
}
expect_stdout: [
"1",
"0",
]
}
issue_3240_3: {
options = {
reduce_funcs: true,
reduce_vars: true,
unused: true,
}
input: {
(function() {
f();
function f(b) {
if (!f.a) f.a = 0;
console.log(f.a.toString());
var g = function() {
(b ? function() {} : function() {
f.a++;
f(1);
})();
};
g();
}
})();
}
expect: {
(function() {
(function f(b) {
if (!f.a) f.a = 0;
console.log(f.a.toString());
var g = function() {
(b ? function() {} : function() {
f.a++;
f(1);
})();
};
g();
})();
})();
}
expect_stdout: [
"0",
"1",
]
}
issue_3240_4: {
options = {
passes: 2,
reduce_funcs: true,
reduce_vars: true,
unused: true,
}
input: {
(function() {
f();
function f(b) {
if (!f.a) f.a = 0;
console.log(f.a.toString());
var g = function() {
(b ? function() {} : function() {
f.a++;
f(1);
})();
};
g();
}
})();
}
expect: {
(function() {
(function f(b) {
if (!f.a) f.a = 0;
console.log(f.a.toString());
(function() {
(b ? function() {} : function() {
f.a++;
f(1);
})();
})();
})();
})();
}
expect_stdout: [
"0",
"1",
]
}

View File

@@ -651,7 +651,7 @@ describe("bin/uglifyjs", function() {
});
});
it("Should work with explicit --no-rename", function(done) {
var command = uglifyjscmd + " test/input/rename/input.js -mc --no-rename";
var command = uglifyjscmd + " test/input/rename/input.js -mc passes=2 --no-rename";
exec(command, function(err, stdout, stderr) {
if (err) throw err;
assert.strictEqual(stdout, "function f(n){return function(n){return n}(n)}\n");
@@ -659,7 +659,7 @@ describe("bin/uglifyjs", function() {
});
});
it("Should work with implicit --rename", function(done) {
var command = uglifyjscmd + " test/input/rename/input.js -mc";
var command = uglifyjscmd + " test/input/rename/input.js -mc passes=2";
exec(command, function(err, stdout, stderr) {
if (err) throw err;
assert.strictEqual(stdout, "function f(n){return n}\n");
@@ -667,7 +667,7 @@ describe("bin/uglifyjs", function() {
});
});
it("Should work with implicit --no-rename", function(done) {
var command = uglifyjscmd + " test/input/rename/input.js -c";
var command = uglifyjscmd + " test/input/rename/input.js -c passes=2";
exec(command, function(err, stdout, stderr) {
if (err) throw err;
assert.strictEqual(stdout, "function f(x){return function(x){return x}(x)}\n");