Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea999b0e92 | ||
|
|
ce7e220de4 | ||
|
|
2bdaca10ae | ||
|
|
aa0029204e | ||
|
|
f352bcec3a | ||
|
|
08514030f4 | ||
|
|
694ca5d045 | ||
|
|
57fb58b263 | ||
|
|
18c1c9b38a |
259
lib/compress.js
259
lib/compress.js
@@ -450,8 +450,7 @@ merge(Compressor.prototype, {
|
|||||||
return value instanceof AST_Node && def.fixed.parent_scope === scope;
|
return value instanceof AST_Node && def.fixed.parent_scope === scope;
|
||||||
}
|
}
|
||||||
return all(def.orig, function(sym) {
|
return all(def.orig, function(sym) {
|
||||||
return !(sym instanceof AST_SymbolDefun
|
return !(sym instanceof AST_SymbolDefun || sym instanceof AST_SymbolLambda);
|
||||||
|| sym instanceof AST_SymbolLambda);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1482,14 +1481,26 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function get_rhs(expr) {
|
function get_rhs(expr) {
|
||||||
if (!(candidate instanceof AST_Assign && candidate.operator == "=")) return;
|
return candidate instanceof AST_Assign && candidate.operator == "=" && candidate.right;
|
||||||
return candidate.right;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_rvalue(expr) {
|
function get_rvalue(expr) {
|
||||||
return expr[expr instanceof AST_Assign ? "right" : "value"];
|
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) {
|
function foldable(expr) {
|
||||||
if (expr instanceof AST_SymbolRef) {
|
if (expr instanceof AST_SymbolRef) {
|
||||||
var value = expr.evaluate(compressor);
|
var value = expr.evaluate(compressor);
|
||||||
@@ -1502,7 +1513,7 @@ merge(Compressor.prototype, {
|
|||||||
return rhs_fuzzy_match(expr.evaluate(compressor), rhs_exact_match);
|
return rhs_fuzzy_match(expr.evaluate(compressor), rhs_exact_match);
|
||||||
}
|
}
|
||||||
if (!(lhs instanceof AST_SymbolRef)) return false;
|
if (!(lhs instanceof AST_SymbolRef)) return false;
|
||||||
if (expr.has_side_effects(compressor)) return false;
|
if (!invariant(expr)) return false;
|
||||||
var circular;
|
var circular;
|
||||||
var def = lhs.definition();
|
var def = lhs.definition();
|
||||||
expr.walk(new TreeWalker(function(node) {
|
expr.walk(new TreeWalker(function(node) {
|
||||||
@@ -1699,6 +1710,19 @@ merge(Compressor.prototype, {
|
|||||||
continue;
|
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);
|
var ab = aborts(stat.alternative);
|
||||||
if (can_merge_flow(ab)) {
|
if (can_merge_flow(ab)) {
|
||||||
if (ab.label) {
|
if (ab.label) {
|
||||||
@@ -2968,19 +2992,21 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
// determine if expression has side effects
|
// determine if expression has side effects
|
||||||
(function(def) {
|
(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) {
|
function any(list, compressor) {
|
||||||
for (var i = list.length; --i >= 0;)
|
for (var i = list.length; --i >= 0;)
|
||||||
if (list[i].has_side_effects(compressor))
|
if (list[i].has_side_effects(compressor))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
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) {
|
def(AST_Block, function(compressor) {
|
||||||
return any(this.body, compressor);
|
return any(this.body, compressor);
|
||||||
});
|
});
|
||||||
@@ -2992,19 +3018,24 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
return any(this.args, compressor);
|
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) {
|
def(AST_Case, function(compressor) {
|
||||||
return this.expression.has_side_effects(compressor)
|
return this.expression.has_side_effects(compressor)
|
||||||
|| any(this.body, compressor);
|
|| any(this.body, compressor);
|
||||||
});
|
});
|
||||||
def(AST_Try, function(compressor) {
|
def(AST_Conditional, function(compressor) {
|
||||||
return any(this.body, compressor)
|
return this.condition.has_side_effects(compressor)
|
||||||
|| this.bcatch && this.bcatch.has_side_effects(compressor)
|
|| this.consequent.has_side_effects(compressor)
|
||||||
|| this.bfinally && this.bfinally.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) {
|
def(AST_If, function(compressor) {
|
||||||
return this.condition.has_side_effects(compressor)
|
return this.condition.has_side_effects(compressor)
|
||||||
|| this.body && this.body.has_side_effects(compressor)
|
|| this.body && this.body.has_side_effects(compressor)
|
||||||
@@ -3013,41 +3044,13 @@ merge(Compressor.prototype, {
|
|||||||
def(AST_LabeledStatement, function(compressor) {
|
def(AST_LabeledStatement, function(compressor) {
|
||||||
return this.body.has_side_effects(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_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) {
|
def(AST_Object, function(compressor) {
|
||||||
return any(this.properties, compressor);
|
return any(this.properties, compressor);
|
||||||
});
|
});
|
||||||
def(AST_ObjectProperty, function(compressor) {
|
def(AST_ObjectProperty, function(compressor) {
|
||||||
return this.value.has_side_effects(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) {
|
def(AST_Sub, function(compressor) {
|
||||||
return this.expression.may_throw_on_access(compressor)
|
return this.expression.may_throw_on_access(compressor)
|
||||||
|| this.expression.has_side_effects(compressor)
|
|| this.expression.has_side_effects(compressor)
|
||||||
@@ -3056,8 +3059,26 @@ merge(Compressor.prototype, {
|
|||||||
def(AST_Sequence, function(compressor) {
|
def(AST_Sequence, function(compressor) {
|
||||||
return any(this.expressions, compressor);
|
return any(this.expressions, compressor);
|
||||||
});
|
});
|
||||||
def(AST_Definitions, function(compressor) {
|
def(AST_SimpleStatement, function(compressor) {
|
||||||
return any(this.definitions, 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) {
|
def(AST_VarDef, function(compressor) {
|
||||||
return this.value;
|
return this.value;
|
||||||
@@ -3316,13 +3337,14 @@ merge(Compressor.prototype, {
|
|||||||
} else if (node instanceof AST_Unary && node.write_only) {
|
} else if (node instanceof AST_Unary && node.write_only) {
|
||||||
sym = node.expression;
|
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)) {
|
while (sym instanceof AST_PropAccess && !sym.expression.may_throw_on_access(compressor)) {
|
||||||
if (sym instanceof AST_Sub) props.unshift(sym.property);
|
if (sym instanceof AST_Sub) props.unshift(sym.property);
|
||||||
sym = sym.expression;
|
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 = [];
|
||||||
var in_use_ids = Object.create(null); // avoid expensive linear scans of 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();
|
var parent = tt.parent();
|
||||||
if (drop_vars) {
|
if (drop_vars) {
|
||||||
var props = [], sym = assign_as_unused(node, props);
|
var props = [], sym = assign_as_unused(node, props);
|
||||||
if (sym instanceof AST_SymbolRef) {
|
if (sym) {
|
||||||
var def = sym.definition();
|
var def = sym.definition();
|
||||||
var in_use = def.id in in_use_ids;
|
var in_use = def.id in in_use_ids;
|
||||||
var value = null;
|
var value = null;
|
||||||
@@ -3616,8 +3638,7 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
function scan_ref_scoped(node, descend) {
|
function scan_ref_scoped(node, descend) {
|
||||||
var node_def, props = [], sym = assign_as_unused(node, props);
|
var node_def, props = [], sym = assign_as_unused(node, props);
|
||||||
if (sym instanceof AST_SymbolRef
|
if (sym && self.variables.get(sym.name) === (node_def = sym.definition())) {
|
||||||
&& self.variables.get(sym.name) === (node_def = sym.definition())) {
|
|
||||||
props.forEach(function(prop) {
|
props.forEach(function(prop) {
|
||||||
prop.walk(tw);
|
prop.walk(tw);
|
||||||
});
|
});
|
||||||
@@ -5730,38 +5751,34 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
var parent = compressor.parent();
|
var parent = compressor.parent();
|
||||||
if (compressor.option("reduce_vars") && is_lhs(self, parent) !== self) {
|
if (compressor.option("reduce_vars") && is_lhs(self, parent) !== self) {
|
||||||
var d = self.definition();
|
var def = self.definition();
|
||||||
var fixed = self.fixed_value();
|
var fixed = self.fixed_value();
|
||||||
var single_use = d.single_use
|
var single_use = def.single_use && !(parent instanceof AST_Call && parent.is_expr_pure(compressor));
|
||||||
&& !(parent instanceof AST_Call && parent.is_expr_pure(compressor));
|
|
||||||
if (single_use && fixed instanceof AST_Lambda) {
|
if (single_use && fixed instanceof AST_Lambda) {
|
||||||
if (d.scope !== self.scope
|
if (def.scope !== self.scope
|
||||||
&& (!compressor.option("reduce_funcs")
|
&& (!compressor.option("reduce_funcs") || def.escaped == 1 || fixed.inlined)) {
|
||||||
|| d.escaped == 1
|
|
||||||
|| fixed.inlined)) {
|
|
||||||
single_use = false;
|
single_use = false;
|
||||||
} else if (recursive_ref(compressor, d)) {
|
} else if (recursive_ref(compressor, def)) {
|
||||||
single_use = false;
|
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);
|
single_use = fixed.is_constant_expression(self.scope);
|
||||||
if (single_use == "f") {
|
if (single_use == "f") {
|
||||||
var scope = self.scope;
|
var scope = self.scope;
|
||||||
do {
|
do if (scope instanceof AST_Defun || scope instanceof AST_Function) {
|
||||||
if (scope instanceof AST_Defun || scope instanceof AST_Function) {
|
scope.inlined = true;
|
||||||
scope.inlined = true;
|
|
||||||
}
|
|
||||||
} while (scope = scope.parent_scope);
|
} while (scope = scope.parent_scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (single_use && fixed) {
|
if (single_use && fixed) {
|
||||||
|
def.single_use = false;
|
||||||
if (fixed instanceof AST_Defun) {
|
if (fixed instanceof AST_Defun) {
|
||||||
fixed._squeezed = true;
|
fixed._squeezed = true;
|
||||||
fixed = make_node(AST_Function, fixed, fixed);
|
fixed = make_node(AST_Function, fixed, fixed);
|
||||||
fixed.name = make_node(AST_SymbolLambda, fixed.name, fixed.name);
|
fixed.name = make_node(AST_SymbolLambda, fixed.name, fixed.name);
|
||||||
}
|
}
|
||||||
var value;
|
var value;
|
||||||
if (d.recursive_refs > 0) {
|
if (def.recursive_refs > 0) {
|
||||||
value = fixed.clone(true);
|
value = fixed.clone(true);
|
||||||
var defun_def = value.name.definition();
|
var defun_def = value.name.definition();
|
||||||
var lambda_def = value.variables.get(value.name.name);
|
var lambda_def = value.variables.get(value.name.name);
|
||||||
@@ -5773,9 +5790,13 @@ merge(Compressor.prototype, {
|
|||||||
lambda_def = value.def_function(name);
|
lambda_def = value.def_function(name);
|
||||||
}
|
}
|
||||||
value.walk(new TreeWalker(function(node) {
|
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;
|
node.thedef = lambda_def;
|
||||||
lambda_def.references.push(node);
|
lambda_def.references.push(node);
|
||||||
|
} else {
|
||||||
|
def.single_use = false;
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
@@ -5784,13 +5805,12 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
if (fixed && d.should_replace === undefined) {
|
if (fixed && def.should_replace === undefined) {
|
||||||
var init;
|
var init;
|
||||||
if (fixed instanceof AST_This) {
|
if (fixed instanceof AST_This) {
|
||||||
if (!(d.orig[0] instanceof AST_SymbolFunarg)
|
if (!(def.orig[0] instanceof AST_SymbolFunarg) && all(def.references, function(ref) {
|
||||||
&& all(d.references, function(ref) {
|
return def.scope === ref.scope;
|
||||||
return d.scope === ref.scope;
|
})) {
|
||||||
})) {
|
|
||||||
init = fixed;
|
init = fixed;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -5814,18 +5834,18 @@ merge(Compressor.prototype, {
|
|||||||
return result === init || result === fixed ? result.clone(true) : result;
|
return result === init || result === fixed ? result.clone(true) : result;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
var name_length = d.name.length;
|
var name_length = def.name.length;
|
||||||
var overhead = 0;
|
var overhead = 0;
|
||||||
if (compressor.option("unused") && !compressor.exposed(d)) {
|
if (compressor.option("unused") && !compressor.exposed(def)) {
|
||||||
overhead = (name_length + 2 + value_length) / (d.references.length - d.assignments);
|
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 {
|
} else {
|
||||||
d.should_replace = false;
|
def.should_replace = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (d.should_replace) {
|
if (def.should_replace) {
|
||||||
return d.should_replace();
|
return def.should_replace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
@@ -6027,22 +6047,26 @@ merge(Compressor.prototype, {
|
|||||||
// |
|
// |
|
||||||
// v
|
// v
|
||||||
// exp = foo ? something : something_else;
|
// exp = foo ? something : something_else;
|
||||||
if (consequent instanceof AST_Assign
|
var seq_tail = consequent.tail_node();
|
||||||
&& alternative instanceof AST_Assign
|
if (seq_tail instanceof AST_Assign) {
|
||||||
&& consequent.operator == alternative.operator
|
var is_eq = seq_tail.operator == "=";
|
||||||
&& consequent.left.equivalent_to(alternative.left)
|
var alt_tail = is_eq ? alternative.tail_node() : alternative;
|
||||||
&& (!self.condition.has_side_effects(compressor)
|
if ((is_eq || consequent instanceof AST_Assign)
|
||||||
|| consequent.operator == "="
|
&& alt_tail instanceof AST_Assign
|
||||||
&& !consequent.left.has_side_effects(compressor))) {
|
&& seq_tail.operator == alt_tail.operator
|
||||||
return make_node(AST_Assign, self, {
|
&& seq_tail.left.equivalent_to(alt_tail.left)
|
||||||
operator: consequent.operator,
|
&& (!condition.has_side_effects(compressor)
|
||||||
left: consequent.left,
|
|| is_eq && !seq_tail.left.has_side_effects(compressor))) {
|
||||||
right: make_node(AST_Conditional, self, {
|
return make_node(AST_Assign, self, {
|
||||||
condition: self.condition,
|
operator: seq_tail.operator,
|
||||||
consequent: consequent.right,
|
left: seq_tail.left,
|
||||||
alternative: alternative.right
|
right: make_node(AST_Conditional, self, {
|
||||||
})
|
condition: condition,
|
||||||
});
|
consequent: pop_lhs(consequent),
|
||||||
|
alternative: pop_lhs(alternative)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// x ? y(a) : y(b) --> y(x ? a : b)
|
// x ? y(a) : y(b) --> y(x ? a : b)
|
||||||
var arg_index;
|
var arg_index;
|
||||||
@@ -6051,12 +6075,12 @@ merge(Compressor.prototype, {
|
|||||||
&& consequent.args.length > 0
|
&& consequent.args.length > 0
|
||||||
&& consequent.args.length == alternative.args.length
|
&& consequent.args.length == alternative.args.length
|
||||||
&& consequent.expression.equivalent_to(alternative.expression)
|
&& consequent.expression.equivalent_to(alternative.expression)
|
||||||
&& !self.condition.has_side_effects(compressor)
|
&& !condition.has_side_effects(compressor)
|
||||||
&& !consequent.expression.has_side_effects(compressor)
|
&& !consequent.expression.has_side_effects(compressor)
|
||||||
&& typeof (arg_index = single_arg_diff()) == "number") {
|
&& typeof (arg_index = single_arg_diff()) == "number") {
|
||||||
var node = consequent.clone();
|
var node = consequent.clone();
|
||||||
node.args[arg_index] = make_node(AST_Conditional, self, {
|
node.args[arg_index] = make_node(AST_Conditional, self, {
|
||||||
condition: self.condition,
|
condition: condition,
|
||||||
consequent: consequent.args[arg_index],
|
consequent: consequent.args[arg_index],
|
||||||
alternative: alternative.args[arg_index]
|
alternative: alternative.args[arg_index]
|
||||||
});
|
});
|
||||||
@@ -6067,7 +6091,7 @@ merge(Compressor.prototype, {
|
|||||||
&& consequent.alternative.equivalent_to(alternative)) {
|
&& consequent.alternative.equivalent_to(alternative)) {
|
||||||
return make_node(AST_Conditional, self, {
|
return make_node(AST_Conditional, self, {
|
||||||
condition: make_node(AST_Binary, self, {
|
condition: make_node(AST_Binary, self, {
|
||||||
left: self.condition,
|
left: condition,
|
||||||
operator: "&&",
|
operator: "&&",
|
||||||
right: consequent.condition
|
right: consequent.condition
|
||||||
}),
|
}),
|
||||||
@@ -6078,7 +6102,7 @@ merge(Compressor.prototype, {
|
|||||||
// x ? y : y --> x, y
|
// x ? y : y --> x, y
|
||||||
if (consequent.equivalent_to(alternative)) {
|
if (consequent.equivalent_to(alternative)) {
|
||||||
return make_sequence(self, [
|
return make_sequence(self, [
|
||||||
self.condition,
|
condition,
|
||||||
consequent
|
consequent
|
||||||
]).optimize(compressor);
|
]).optimize(compressor);
|
||||||
}
|
}
|
||||||
@@ -6087,7 +6111,7 @@ merge(Compressor.prototype, {
|
|||||||
&& consequent.tail_node().equivalent_to(alternative.tail_node())) {
|
&& consequent.tail_node().equivalent_to(alternative.tail_node())) {
|
||||||
return make_sequence(self, [
|
return make_sequence(self, [
|
||||||
make_node(AST_Conditional, self, {
|
make_node(AST_Conditional, self, {
|
||||||
condition: self.condition,
|
condition: condition,
|
||||||
consequent: pop_seq(consequent),
|
consequent: pop_seq(consequent),
|
||||||
alternative: pop_seq(alternative)
|
alternative: pop_seq(alternative)
|
||||||
}),
|
}),
|
||||||
@@ -6102,7 +6126,7 @@ merge(Compressor.prototype, {
|
|||||||
operator: "||",
|
operator: "||",
|
||||||
left: make_node(AST_Binary, self, {
|
left: make_node(AST_Binary, self, {
|
||||||
operator: "&&",
|
operator: "&&",
|
||||||
left: self.condition,
|
left: condition,
|
||||||
right: consequent.left
|
right: consequent.left
|
||||||
}),
|
}),
|
||||||
right: alternative
|
right: alternative
|
||||||
@@ -6112,24 +6136,24 @@ merge(Compressor.prototype, {
|
|||||||
if (is_true(self.consequent)) {
|
if (is_true(self.consequent)) {
|
||||||
if (is_false(self.alternative)) {
|
if (is_false(self.alternative)) {
|
||||||
// c ? true : false ---> !!c
|
// c ? true : false ---> !!c
|
||||||
return booleanize(self.condition);
|
return booleanize(condition);
|
||||||
}
|
}
|
||||||
// c ? true : x ---> !!c || x
|
// c ? true : x ---> !!c || x
|
||||||
return make_node(AST_Binary, self, {
|
return make_node(AST_Binary, self, {
|
||||||
operator: "||",
|
operator: "||",
|
||||||
left: booleanize(self.condition),
|
left: booleanize(condition),
|
||||||
right: self.alternative
|
right: self.alternative
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (is_false(self.consequent)) {
|
if (is_false(self.consequent)) {
|
||||||
if (is_true(self.alternative)) {
|
if (is_true(self.alternative)) {
|
||||||
// c ? false : true ---> !c
|
// c ? false : true ---> !c
|
||||||
return booleanize(self.condition.negate(compressor));
|
return booleanize(condition.negate(compressor));
|
||||||
}
|
}
|
||||||
// c ? false : x ---> !c && x
|
// c ? false : x ---> !c && x
|
||||||
return make_node(AST_Binary, self, {
|
return make_node(AST_Binary, self, {
|
||||||
operator: "&&",
|
operator: "&&",
|
||||||
left: booleanize(self.condition.negate(compressor)),
|
left: booleanize(condition.negate(compressor)),
|
||||||
right: self.alternative
|
right: self.alternative
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -6137,7 +6161,7 @@ merge(Compressor.prototype, {
|
|||||||
// c ? x : true ---> !c || x
|
// c ? x : true ---> !c || x
|
||||||
return make_node(AST_Binary, self, {
|
return make_node(AST_Binary, self, {
|
||||||
operator: "||",
|
operator: "||",
|
||||||
left: booleanize(self.condition.negate(compressor)),
|
left: booleanize(condition.negate(compressor)),
|
||||||
right: self.consequent
|
right: self.consequent
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -6145,7 +6169,7 @@ merge(Compressor.prototype, {
|
|||||||
// c ? x : false ---> !!c && x
|
// c ? x : false ---> !!c && x
|
||||||
return make_node(AST_Binary, self, {
|
return make_node(AST_Binary, self, {
|
||||||
operator: "&&",
|
operator: "&&",
|
||||||
left: booleanize(self.condition),
|
left: booleanize(condition),
|
||||||
right: self.consequent
|
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) {
|
function pop_seq(node) {
|
||||||
if (!(node instanceof AST_Sequence)) return make_node(AST_Number, node, {
|
if (!(node instanceof AST_Sequence)) return make_node(AST_Number, node, {
|
||||||
value: 0
|
value: 0
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"version": "3.4.7",
|
"version": "3.4.9",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
"LICENSE"
|
"LICENSE"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"commander": "~2.16.0",
|
"commander": "~2.17.1",
|
||||||
"source-map": "~0.6.1"
|
"source-map": "~0.6.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -5827,3 +5827,183 @@ issue_3215_4: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "number"
|
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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1292,3 +1292,95 @@ to_and_or: {
|
|||||||
}
|
}
|
||||||
expect_stdout: true
|
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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1982,3 +1982,26 @@ issue_3192: {
|
|||||||
"foo bar",
|
"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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -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",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
@@ -5354,6 +5354,7 @@ issue_2774: {
|
|||||||
|
|
||||||
issue_2799_1: {
|
issue_2799_1: {
|
||||||
options = {
|
options = {
|
||||||
|
passes: 2,
|
||||||
reduce_funcs: true,
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -6429,3 +6430,159 @@ issue_3140_5: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "1"
|
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",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
@@ -651,7 +651,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with explicit --no-rename", function(done) {
|
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) {
|
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}(n)}\n");
|
||||||
@@ -659,7 +659,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with implicit --rename", function(done) {
|
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) {
|
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}\n");
|
||||||
@@ -667,7 +667,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with implicit --no-rename", function(done) {
|
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) {
|
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}(x)}\n");
|
||||||
|
|||||||
Reference in New Issue
Block a user