Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b7f6b73f4e | ||
|
|
9469c03ac9 | ||
|
|
d57527697f | ||
|
|
f7ca4f2297 | ||
|
|
c076e7b60d | ||
|
|
4a55bb0be5 | ||
|
|
28ecea50a6 | ||
|
|
9a311705f5 | ||
|
|
ee3fe0f4cd | ||
|
|
87f6e1b091 | ||
|
|
c934fc8142 | ||
|
|
257ddc3bdb | ||
|
|
1ddc05725d | ||
|
|
e6b76a4879 | ||
|
|
a0c3836ba0 | ||
|
|
f8a71b56fd | ||
|
|
11e9bdc427 | ||
|
|
a84564d1a8 | ||
|
|
c595b84032 | ||
|
|
7cb1adf455 | ||
|
|
7bea38a05d | ||
|
|
0f910ee25c | ||
|
|
beb9659778 | ||
|
|
f1a833a7aa | ||
|
|
2e41cd6394 | ||
|
|
09f77c7d4d | ||
|
|
fef0bf9ee0 | ||
|
|
ae740b933f | ||
|
|
ec7f37f314 | ||
|
|
eb48a035e7 |
@@ -443,6 +443,9 @@ to set `true`; it's effectively a shortcut for `foo=true`).
|
|||||||
integer argument larger than 1 to further reduce code size in some cases.
|
integer argument larger than 1 to further reduce code size in some cases.
|
||||||
Note: raising the number of passes will increase uglify compress time.
|
Note: raising the number of passes will increase uglify compress time.
|
||||||
|
|
||||||
|
- `keep_infinity` -- default `false`. Pass `true` to prevent `Infinity` from
|
||||||
|
being compressed into `1/0`, which may cause performance issues on Chrome.
|
||||||
|
|
||||||
### The `unsafe` option
|
### The `unsafe` option
|
||||||
|
|
||||||
It enables some transformations that *might* break code logic in certain
|
It enables some transformations that *might* break code logic in certain
|
||||||
|
|||||||
363
lib/compress.js
363
lib/compress.js
@@ -48,42 +48,44 @@ function Compressor(options, false_by_default) {
|
|||||||
return new Compressor(options, false_by_default);
|
return new Compressor(options, false_by_default);
|
||||||
TreeTransformer.call(this, this.before, this.after);
|
TreeTransformer.call(this, this.before, this.after);
|
||||||
this.options = defaults(options, {
|
this.options = defaults(options, {
|
||||||
sequences : !false_by_default,
|
angular : false,
|
||||||
properties : !false_by_default,
|
booleans : !false_by_default,
|
||||||
|
cascade : !false_by_default,
|
||||||
|
collapse_vars : !false_by_default,
|
||||||
|
comparisons : !false_by_default,
|
||||||
|
conditionals : !false_by_default,
|
||||||
dead_code : !false_by_default,
|
dead_code : !false_by_default,
|
||||||
|
drop_console : false,
|
||||||
drop_debugger : !false_by_default,
|
drop_debugger : !false_by_default,
|
||||||
|
evaluate : !false_by_default,
|
||||||
|
expression : false,
|
||||||
|
global_defs : {},
|
||||||
|
hoist_funs : !false_by_default,
|
||||||
|
hoist_vars : false,
|
||||||
|
if_return : !false_by_default,
|
||||||
|
join_vars : !false_by_default,
|
||||||
|
keep_fargs : true,
|
||||||
|
keep_fnames : false,
|
||||||
|
keep_infinity : false,
|
||||||
|
loops : !false_by_default,
|
||||||
|
negate_iife : !false_by_default,
|
||||||
|
passes : 1,
|
||||||
|
properties : !false_by_default,
|
||||||
|
pure_getters : false,
|
||||||
|
pure_funcs : null,
|
||||||
|
reduce_vars : !false_by_default,
|
||||||
|
screw_ie8 : true,
|
||||||
|
sequences : !false_by_default,
|
||||||
|
side_effects : !false_by_default,
|
||||||
|
switches : !false_by_default,
|
||||||
|
top_retain : null,
|
||||||
|
toplevel : !!(options && options["top_retain"]),
|
||||||
unsafe : false,
|
unsafe : false,
|
||||||
unsafe_comps : false,
|
unsafe_comps : false,
|
||||||
unsafe_math : false,
|
unsafe_math : false,
|
||||||
unsafe_proto : false,
|
unsafe_proto : false,
|
||||||
conditionals : !false_by_default,
|
|
||||||
comparisons : !false_by_default,
|
|
||||||
evaluate : !false_by_default,
|
|
||||||
booleans : !false_by_default,
|
|
||||||
loops : !false_by_default,
|
|
||||||
unused : !false_by_default,
|
unused : !false_by_default,
|
||||||
toplevel : !!(options && options["top_retain"]),
|
|
||||||
top_retain : null,
|
|
||||||
hoist_funs : !false_by_default,
|
|
||||||
keep_fargs : true,
|
|
||||||
keep_fnames : false,
|
|
||||||
hoist_vars : false,
|
|
||||||
if_return : !false_by_default,
|
|
||||||
join_vars : !false_by_default,
|
|
||||||
collapse_vars : !false_by_default,
|
|
||||||
reduce_vars : !false_by_default,
|
|
||||||
cascade : !false_by_default,
|
|
||||||
side_effects : !false_by_default,
|
|
||||||
pure_getters : false,
|
|
||||||
pure_funcs : null,
|
|
||||||
negate_iife : !false_by_default,
|
|
||||||
screw_ie8 : true,
|
|
||||||
drop_console : false,
|
|
||||||
angular : false,
|
|
||||||
expression : false,
|
|
||||||
warnings : true,
|
warnings : true,
|
||||||
global_defs : {},
|
|
||||||
passes : 1,
|
|
||||||
}, true);
|
}, true);
|
||||||
var pure_funcs = this.options["pure_funcs"];
|
var pure_funcs = this.options["pure_funcs"];
|
||||||
if (typeof pure_funcs == "function") {
|
if (typeof pure_funcs == "function") {
|
||||||
@@ -196,11 +198,10 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
AST_Node.DEFMETHOD("equivalent_to", function(node){
|
AST_Node.DEFMETHOD("equivalent_to", function(node){
|
||||||
// XXX: this is a rather expensive way to test two node's equivalence:
|
return this.TYPE == node.TYPE && this.print_to_string() == node.print_to_string();
|
||||||
return this.print_to_string() == node.print_to_string();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Node.DEFMETHOD("process_expression", function(insert) {
|
AST_Node.DEFMETHOD("process_expression", function(insert, compressor) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var tt = new TreeTransformer(function(node) {
|
var tt = new TreeTransformer(function(node) {
|
||||||
if (insert && node instanceof AST_SimpleStatement) {
|
if (insert && node instanceof AST_SimpleStatement) {
|
||||||
@@ -209,8 +210,19 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (!insert && node instanceof AST_Return) {
|
if (!insert && node instanceof AST_Return) {
|
||||||
|
if (compressor) {
|
||||||
|
var value = node.value && node.value.drop_side_effect_free(compressor, true);
|
||||||
|
return value ? make_node(AST_SimpleStatement, node, {
|
||||||
|
body: value
|
||||||
|
}) : make_node(AST_EmptyStatement, node);
|
||||||
|
}
|
||||||
return make_node(AST_SimpleStatement, node, {
|
return make_node(AST_SimpleStatement, node, {
|
||||||
body: node.value || make_node(AST_Undefined, node)
|
body: node.value || make_node(AST_UnaryPrefix, node, {
|
||||||
|
operator: "void",
|
||||||
|
expression: make_node(AST_Number, node, {
|
||||||
|
value: 0
|
||||||
|
})
|
||||||
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Lambda && node !== self) {
|
if (node instanceof AST_Lambda && node !== self) {
|
||||||
@@ -397,6 +409,18 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function find_variable(compressor, name) {
|
||||||
|
var scope, i = 0;
|
||||||
|
while (scope = compressor.parent(i++)) {
|
||||||
|
if (scope instanceof AST_Scope) break;
|
||||||
|
if (scope instanceof AST_Catch) {
|
||||||
|
scope = scope.argname.definition().scope;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return scope.find_variable(name);
|
||||||
|
}
|
||||||
|
|
||||||
function make_node(ctor, orig, props) {
|
function make_node(ctor, orig, props) {
|
||||||
if (!props) props = {};
|
if (!props) props = {};
|
||||||
if (orig) {
|
if (orig) {
|
||||||
@@ -413,18 +437,17 @@ merge(Compressor.prototype, {
|
|||||||
value: val
|
value: val
|
||||||
});
|
});
|
||||||
case "number":
|
case "number":
|
||||||
if (isNaN(val)) {
|
if (isNaN(val)) return make_node(AST_NaN, orig);
|
||||||
return make_node(AST_NaN, orig);
|
if (isFinite(val)) {
|
||||||
}
|
return 1 / val < 0 ? make_node(AST_UnaryPrefix, orig, {
|
||||||
|
|
||||||
if ((1 / val) < 0) {
|
|
||||||
return make_node(AST_UnaryPrefix, orig, {
|
|
||||||
operator: "-",
|
operator: "-",
|
||||||
expression: make_node(AST_Number, orig, { value: -val })
|
expression: make_node(AST_Number, orig, { value: -val })
|
||||||
});
|
}) : make_node(AST_Number, orig, { value: val });
|
||||||
}
|
}
|
||||||
|
return val < 0 ? make_node(AST_UnaryPrefix, orig, {
|
||||||
return make_node(AST_Number, orig, { value: val });
|
operator: "-",
|
||||||
|
expression: make_node(AST_Infinity, orig)
|
||||||
|
}) : make_node(AST_Infinity, orig);
|
||||||
case "boolean":
|
case "boolean":
|
||||||
return make_node(val ? AST_True : AST_False, orig);
|
return make_node(val ? AST_True : AST_False, orig);
|
||||||
case "undefined":
|
case "undefined":
|
||||||
@@ -1044,7 +1067,7 @@ merge(Compressor.prototype, {
|
|||||||
stat.value = cons_seq(stat.value);
|
stat.value = cons_seq(stat.value);
|
||||||
}
|
}
|
||||||
else if (stat instanceof AST_Exit) {
|
else if (stat instanceof AST_Exit) {
|
||||||
stat.value = cons_seq(make_node(AST_Undefined, stat));
|
stat.value = cons_seq(make_node(AST_Undefined, stat).transform(compressor));
|
||||||
}
|
}
|
||||||
else if (stat instanceof AST_Switch) {
|
else if (stat instanceof AST_Switch) {
|
||||||
stat.expression = cons_seq(stat.expression);
|
stat.expression = cons_seq(stat.expression);
|
||||||
@@ -1119,8 +1142,12 @@ merge(Compressor.prototype, {
|
|||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
function is_undefined(node) {
|
function is_undefined(node, compressor) {
|
||||||
return node instanceof AST_Undefined || node.is_undefined;
|
return node.is_undefined
|
||||||
|
|| node instanceof AST_Undefined
|
||||||
|
|| node instanceof AST_UnaryPrefix
|
||||||
|
&& node.operator == "void"
|
||||||
|
&& !node.expression.has_side_effects(compressor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -----[ boolean/negation helpers ]----- */
|
/* -----[ boolean/negation helpers ]----- */
|
||||||
@@ -1309,7 +1336,7 @@ merge(Compressor.prototype, {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var unaryPrefix = makePredicate("! ~ - +");
|
var unaryPrefix = makePredicate("! ~ - + void");
|
||||||
AST_Node.DEFMETHOD("is_constant", function(){
|
AST_Node.DEFMETHOD("is_constant", function(){
|
||||||
// Accomodate when compress option evaluate=false
|
// Accomodate when compress option evaluate=false
|
||||||
// as well as the common constant expressions !0 and -1
|
// as well as the common constant expressions !0 and -1
|
||||||
@@ -1896,8 +1923,7 @@ merge(Compressor.prototype, {
|
|||||||
if (def.value) def.value = def.value.transform(tt);
|
if (def.value) def.value = def.value.transform(tt);
|
||||||
var sym = def.name.definition();
|
var sym = def.name.definition();
|
||||||
if (sym.id in in_use_ids) return true;
|
if (sym.id in in_use_ids) return true;
|
||||||
if (sym.orig[0] instanceof AST_SymbolCatch
|
if (sym.orig[0] instanceof AST_SymbolCatch) {
|
||||||
&& sym.scope.parent_scope.find_variable(def.name).orig[0] === def.name) {
|
|
||||||
def.value = def.value && def.value.drop_side_effect_free(compressor);
|
def.value = def.value && def.value.drop_side_effect_free(compressor);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -2156,7 +2182,7 @@ merge(Compressor.prototype, {
|
|||||||
if (this.expression instanceof AST_Function
|
if (this.expression instanceof AST_Function
|
||||||
&& (!this.expression.name || !this.expression.name.definition().references.length)) {
|
&& (!this.expression.name || !this.expression.name.definition().references.length)) {
|
||||||
var node = this.clone();
|
var node = this.clone();
|
||||||
node.expression = node.expression.process_expression(false);
|
node.expression = node.expression.process_expression(false, compressor);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
@@ -2513,6 +2539,7 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
OPT(AST_Switch, function(self, compressor){
|
OPT(AST_Switch, function(self, compressor){
|
||||||
|
if (!compressor.option("switches")) return self;
|
||||||
var branch;
|
var branch;
|
||||||
var value = self.expression.evaluate(compressor);
|
var value = self.expression.evaluate(compressor);
|
||||||
if (value !== self.expression) {
|
if (value !== self.expression) {
|
||||||
@@ -2520,52 +2547,43 @@ merge(Compressor.prototype, {
|
|||||||
self.expression = best_of_expression(expression, self.expression);
|
self.expression = best_of_expression(expression, self.expression);
|
||||||
}
|
}
|
||||||
if (!compressor.option("dead_code")) return self;
|
if (!compressor.option("dead_code")) return self;
|
||||||
var prev_block;
|
|
||||||
var decl = [];
|
var decl = [];
|
||||||
var body = [];
|
var body = [];
|
||||||
var default_branch;
|
var default_branch;
|
||||||
var exact_match;
|
var exact_match;
|
||||||
var fallthrough;
|
|
||||||
for (var i = 0, len = self.body.length; i < len && !exact_match; i++) {
|
for (var i = 0, len = self.body.length; i < len && !exact_match; i++) {
|
||||||
branch = self.body[i];
|
branch = self.body[i];
|
||||||
if (branch instanceof AST_Default) {
|
if (branch instanceof AST_Default) {
|
||||||
if (!default_branch) default_branch = branch;
|
if (!default_branch) {
|
||||||
else if (!fallthrough) {
|
default_branch = branch;
|
||||||
extract_declarations_from_unreachable_code(compressor, branch, decl);
|
} else {
|
||||||
continue;
|
eliminate_branch(branch, body[body.length - 1]);
|
||||||
}
|
}
|
||||||
} else if (value !== self.expression) {
|
} else if (value !== self.expression) {
|
||||||
var exp = branch.expression.evaluate(compressor);
|
var exp = branch.expression.evaluate(compressor);
|
||||||
if (exp === value) {
|
if (exp === value) {
|
||||||
exact_match = branch;
|
exact_match = branch;
|
||||||
if (default_branch) {
|
if (default_branch) {
|
||||||
body.splice(body.indexOf(default_branch), 1);
|
var default_index = body.indexOf(default_branch);
|
||||||
extract_declarations_from_unreachable_code(compressor, default_branch, decl);
|
body.splice(default_index, 1);
|
||||||
|
eliminate_branch(default_branch, body[default_index - 1]);
|
||||||
default_branch = null;
|
default_branch = null;
|
||||||
}
|
}
|
||||||
} else if (exp !== branch.expression && !fallthrough) {
|
} else if (exp !== branch.expression) {
|
||||||
extract_declarations_from_unreachable_code(compressor, branch, decl);
|
eliminate_branch(branch, body[body.length - 1]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (aborts(branch)) {
|
if (aborts(branch)) {
|
||||||
var block = make_node(AST_BlockStatement, branch, branch).print_to_string();
|
var prev = body[body.length - 1];
|
||||||
if (!fallthrough && prev_block === block) body[body.length - 1].body = [];
|
if (aborts(prev) && prev.body.length == branch.body.length
|
||||||
body.push(branch);
|
&& make_node(AST_BlockStatement, prev, prev).equivalent_to(make_node(AST_BlockStatement, branch, branch))) {
|
||||||
prev_block = block;
|
prev.body = [];
|
||||||
fallthrough = false;
|
}
|
||||||
} else {
|
|
||||||
body.push(branch);
|
|
||||||
prev_block = null;
|
|
||||||
fallthrough = true;
|
|
||||||
}
|
}
|
||||||
|
body.push(branch);
|
||||||
}
|
}
|
||||||
for (; i < len && fallthrough; i++) {
|
while (i < len) eliminate_branch(self.body[i++], body[body.length - 1]);
|
||||||
branch = self.body[i];
|
|
||||||
exact_match.body = exact_match.body.concat(branch.body);
|
|
||||||
fallthrough = !aborts(exact_match);
|
|
||||||
}
|
|
||||||
while (i < len) extract_declarations_from_unreachable_code(compressor, self.body[i++], decl);
|
|
||||||
if (body.length > 0) {
|
if (body.length > 0) {
|
||||||
body[0].body = decl.concat(body[0].body);
|
body[0].body = decl.concat(body[0].body);
|
||||||
}
|
}
|
||||||
@@ -2595,13 +2613,38 @@ merge(Compressor.prototype, {
|
|||||||
has_break = true;
|
has_break = true;
|
||||||
});
|
});
|
||||||
self.walk(tw);
|
self.walk(tw);
|
||||||
if (!has_break) return make_node(AST_BlockStatement, self, body[0]).optimize(compressor);
|
if (!has_break) {
|
||||||
|
body = body[0].body.slice();
|
||||||
|
body.unshift(make_node(AST_SimpleStatement, self.expression, {
|
||||||
|
body: self.expression
|
||||||
|
}));
|
||||||
|
return make_node(AST_BlockStatement, self, {
|
||||||
|
body: body
|
||||||
|
}).optimize(compressor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
|
|
||||||
|
function eliminate_branch(branch, prev) {
|
||||||
|
if (prev && !aborts(prev)) {
|
||||||
|
prev.body = prev.body.concat(branch.body);
|
||||||
|
} else {
|
||||||
|
extract_declarations_from_unreachable_code(compressor, branch, decl);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
OPT(AST_Try, function(self, compressor){
|
OPT(AST_Try, function(self, compressor){
|
||||||
self.body = tighten_body(self.body, compressor);
|
self.body = tighten_body(self.body, compressor);
|
||||||
|
if (self.bcatch && self.bfinally && all(self.bfinally.body, is_empty)) self.bfinally = null;
|
||||||
|
if (all(self.body, is_empty)) {
|
||||||
|
var body = [];
|
||||||
|
if (self.bcatch) extract_declarations_from_unreachable_code(compressor, self.bcatch, body);
|
||||||
|
if (self.bfinally) body = body.concat(self.bfinally.body);
|
||||||
|
return body.length > 0 ? make_node(AST_BlockStatement, self, {
|
||||||
|
body: body
|
||||||
|
}).optimize(compressor) : make_node(AST_EmptyStatement, self);
|
||||||
|
}
|
||||||
return self;
|
return self;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -2868,11 +2911,9 @@ merge(Compressor.prototype, {
|
|||||||
return AST_Seq.from_array(args).transform(compressor);
|
return AST_Seq.from_array(args).transform(compressor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (compressor.option("side_effects")) {
|
if (compressor.option("side_effects") && all(exp.body, is_empty)) {
|
||||||
if (!AST_Block.prototype.has_side_effects.call(exp, compressor)) {
|
var args = self.args.concat(make_node(AST_Undefined, self));
|
||||||
var args = self.args.concat(make_node(AST_Undefined, self));
|
return AST_Seq.from_array(args).transform(compressor);
|
||||||
return AST_Seq.from_array(args).transform(compressor);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (compressor.option("drop_console")) {
|
if (compressor.option("drop_console")) {
|
||||||
@@ -2884,7 +2925,7 @@ merge(Compressor.prototype, {
|
|||||||
if (name instanceof AST_SymbolRef
|
if (name instanceof AST_SymbolRef
|
||||||
&& name.name == "console"
|
&& name.name == "console"
|
||||||
&& name.undeclared()) {
|
&& name.undeclared()) {
|
||||||
return make_node(AST_Undefined, self).transform(compressor);
|
return make_node(AST_Undefined, self).optimize(compressor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2960,7 +3001,7 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (is_undefined(self.cdr)) {
|
if (is_undefined(self.cdr, compressor)) {
|
||||||
return make_node(AST_UnaryPrefix, self, {
|
return make_node(AST_UnaryPrefix, self, {
|
||||||
operator : "void",
|
operator : "void",
|
||||||
expression : self.car
|
expression : self.car
|
||||||
@@ -2999,7 +3040,7 @@ merge(Compressor.prototype, {
|
|||||||
self.expression = e;
|
self.expression = e;
|
||||||
return self;
|
return self;
|
||||||
} else {
|
} else {
|
||||||
return make_node(AST_Undefined, self).transform(compressor);
|
return make_node(AST_Undefined, self).optimize(compressor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (compressor.option("booleans") && compressor.in_boolean_context()) {
|
if (compressor.option("booleans") && compressor.in_boolean_context()) {
|
||||||
@@ -3023,8 +3064,19 @@ merge(Compressor.prototype, {
|
|||||||
})).optimize(compressor);
|
})).optimize(compressor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (self.operator == "-" && e instanceof AST_Infinity) {
|
||||||
|
e = e.transform(compressor);
|
||||||
|
}
|
||||||
|
if (e instanceof AST_Binary
|
||||||
|
&& (self.operator == "+" || self.operator == "-")
|
||||||
|
&& (e.operator == "*" || e.operator == "/" || e.operator == "%")) {
|
||||||
|
self.expression = e.left;
|
||||||
|
e.left = self;
|
||||||
|
return e.optimize(compressor);
|
||||||
|
}
|
||||||
// avoids infinite recursion of numerals
|
// avoids infinite recursion of numerals
|
||||||
if (self.operator != "-" || !(self.expression instanceof AST_Number)) {
|
if (self.operator != "-"
|
||||||
|
|| !(e instanceof AST_Number || e instanceof AST_Infinity)) {
|
||||||
var ev = self.evaluate(compressor);
|
var ev = self.evaluate(compressor);
|
||||||
if (ev !== self) {
|
if (ev !== self) {
|
||||||
ev = make_node_from_constant(ev, self).optimize(compressor);
|
ev = make_node_from_constant(ev, self).optimize(compressor);
|
||||||
@@ -3067,8 +3119,8 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
OPT(AST_Binary, function(self, compressor){
|
OPT(AST_Binary, function(self, compressor){
|
||||||
function reversible() {
|
function reversible() {
|
||||||
return self.left instanceof AST_Constant
|
return self.left.is_constant()
|
||||||
|| self.right instanceof AST_Constant
|
|| self.right.is_constant()
|
||||||
|| !self.left.has_side_effects(compressor)
|
|| !self.left.has_side_effects(compressor)
|
||||||
&& !self.right.has_side_effects(compressor);
|
&& !self.right.has_side_effects(compressor);
|
||||||
}
|
}
|
||||||
@@ -3081,8 +3133,8 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (commutativeOperators(self.operator)) {
|
if (commutativeOperators(self.operator)) {
|
||||||
if (self.right instanceof AST_Constant
|
if (self.right.is_constant()
|
||||||
&& !(self.left instanceof AST_Constant)) {
|
&& !self.left.is_constant()) {
|
||||||
// if right is a constant, whatever side effects the
|
// if right is a constant, whatever side effects the
|
||||||
// left side might have could not influence the
|
// left side might have could not influence the
|
||||||
// result. hence, force switch.
|
// result. hence, force switch.
|
||||||
@@ -3120,42 +3172,7 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (compressor.option("booleans") && compressor.in_boolean_context()) switch (self.operator) {
|
if (compressor.option("booleans") && self.operator == "+" && compressor.in_boolean_context()) {
|
||||||
case "&&":
|
|
||||||
var ll = self.left.evaluate(compressor);
|
|
||||||
var rr = self.right.evaluate(compressor);
|
|
||||||
if (!ll || !rr) {
|
|
||||||
compressor.warn("Boolean && always false [{file}:{line},{col}]", self.start);
|
|
||||||
return make_node(AST_Seq, self, {
|
|
||||||
car: self.left,
|
|
||||||
cdr: make_node(AST_False, self)
|
|
||||||
}).optimize(compressor);
|
|
||||||
}
|
|
||||||
if (ll !== self.left && ll) {
|
|
||||||
return self.right.optimize(compressor);
|
|
||||||
}
|
|
||||||
if (rr !== self.right && rr) {
|
|
||||||
return self.left.optimize(compressor);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "||":
|
|
||||||
var ll = self.left.evaluate(compressor);
|
|
||||||
var rr = self.right.evaluate(compressor);
|
|
||||||
if (ll !== self.left && ll || rr !== self.right && rr) {
|
|
||||||
compressor.warn("Boolean || always true [{file}:{line},{col}]", self.start);
|
|
||||||
return make_node(AST_Seq, self, {
|
|
||||||
car: self.left,
|
|
||||||
cdr: make_node(AST_True, self)
|
|
||||||
}).optimize(compressor);
|
|
||||||
}
|
|
||||||
if (!ll) {
|
|
||||||
return self.right.optimize(compressor);
|
|
||||||
}
|
|
||||||
if (!rr) {
|
|
||||||
return self.left.optimize(compressor);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "+":
|
|
||||||
var ll = self.left.evaluate(compressor);
|
var ll = self.left.evaluate(compressor);
|
||||||
var rr = self.right.evaluate(compressor);
|
var rr = self.right.evaluate(compressor);
|
||||||
if (ll && typeof ll == "string") {
|
if (ll && typeof ll == "string") {
|
||||||
@@ -3172,7 +3189,6 @@ merge(Compressor.prototype, {
|
|||||||
cdr: make_node(AST_True, self)
|
cdr: make_node(AST_True, self)
|
||||||
}).optimize(compressor);
|
}).optimize(compressor);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (compressor.option("comparisons") && self.is_boolean()) {
|
if (compressor.option("comparisons") && self.is_boolean()) {
|
||||||
if (!(compressor.parent() instanceof AST_Binary)
|
if (!(compressor.parent() instanceof AST_Binary)
|
||||||
@@ -3213,24 +3229,48 @@ merge(Compressor.prototype, {
|
|||||||
if (compressor.option("evaluate")) {
|
if (compressor.option("evaluate")) {
|
||||||
switch (self.operator) {
|
switch (self.operator) {
|
||||||
case "&&":
|
case "&&":
|
||||||
if (self.left.is_constant()) {
|
var ll = self.left.evaluate(compressor);
|
||||||
if (self.left.constant_value(compressor)) {
|
if (!ll) {
|
||||||
compressor.warn("Condition left of && always true [{file}:{line},{col}]", self.start);
|
compressor.warn("Condition left of && always false [{file}:{line},{col}]", self.start);
|
||||||
return maintain_this_binding(compressor.parent(), self, self.right);
|
return maintain_this_binding(compressor.parent(), self, self.left).optimize(compressor);
|
||||||
} else {
|
} else if (ll !== self.left) {
|
||||||
compressor.warn("Condition left of && always false [{file}:{line},{col}]", self.start);
|
compressor.warn("Condition left of && always true [{file}:{line},{col}]", self.start);
|
||||||
return maintain_this_binding(compressor.parent(), self, self.left);
|
return maintain_this_binding(compressor.parent(), self, self.right).optimize(compressor);
|
||||||
|
}
|
||||||
|
if (compressor.option("booleans") && compressor.in_boolean_context()) {
|
||||||
|
var rr = self.right.evaluate(compressor);
|
||||||
|
if (!rr) {
|
||||||
|
compressor.warn("Boolean && always false [{file}:{line},{col}]", self.start);
|
||||||
|
return make_node(AST_Seq, self, {
|
||||||
|
car: self.left,
|
||||||
|
cdr: make_node(AST_False, self)
|
||||||
|
}).optimize(compressor);
|
||||||
|
} else if (rr !== self.right) {
|
||||||
|
compressor.warn("Dropping side-effect-free && in boolean context [{file}:{line},{col}]", self.start);
|
||||||
|
return self.left.optimize(compressor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "||":
|
case "||":
|
||||||
if (self.left.is_constant()) {
|
var ll = self.left.evaluate(compressor);
|
||||||
if (self.left.constant_value(compressor)) {
|
if (!ll) {
|
||||||
compressor.warn("Condition left of || always true [{file}:{line},{col}]", self.start);
|
compressor.warn("Condition left of || always false [{file}:{line},{col}]", self.start);
|
||||||
return maintain_this_binding(compressor.parent(), self, self.left);
|
return maintain_this_binding(compressor.parent(), self, self.right).optimize(compressor);
|
||||||
} else {
|
} else if (ll !== self.left) {
|
||||||
compressor.warn("Condition left of || always false [{file}:{line},{col}]", self.start);
|
compressor.warn("Condition left of || always true [{file}:{line},{col}]", self.start);
|
||||||
return maintain_this_binding(compressor.parent(), self, self.right);
|
return maintain_this_binding(compressor.parent(), self, self.left).optimize(compressor);
|
||||||
|
}
|
||||||
|
if (compressor.option("booleans") && compressor.in_boolean_context()) {
|
||||||
|
var rr = self.right.evaluate(compressor);
|
||||||
|
if (!rr) {
|
||||||
|
compressor.warn("Dropping side-effect-free || in boolean context [{file}:{line},{col}]", self.start);
|
||||||
|
return self.left.optimize(compressor);
|
||||||
|
} else if (rr !== self.right) {
|
||||||
|
compressor.warn("Boolean || always true [{file}:{line},{col}]", self.start);
|
||||||
|
return make_node(AST_Seq, self, {
|
||||||
|
car: self.left,
|
||||||
|
cdr: make_node(AST_True, self)
|
||||||
|
}).optimize(compressor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -3486,29 +3526,50 @@ merge(Compressor.prototype, {
|
|||||||
return self;
|
return self;
|
||||||
});
|
});
|
||||||
|
|
||||||
OPT(AST_Infinity, function (self, compressor) {
|
|
||||||
return make_node(AST_Binary, self, {
|
|
||||||
operator : '/',
|
|
||||||
left : make_node(AST_Number, self, {value: 1}),
|
|
||||||
right : make_node(AST_Number, self, {value: 0})
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
OPT(AST_Undefined, function(self, compressor){
|
OPT(AST_Undefined, function(self, compressor){
|
||||||
if (compressor.option("unsafe")) {
|
if (compressor.option("unsafe")) {
|
||||||
var scope = compressor.find_parent(AST_Scope);
|
var undef = find_variable(compressor, "undefined");
|
||||||
var undef = scope.find_variable("undefined");
|
|
||||||
if (undef) {
|
if (undef) {
|
||||||
var ref = make_node(AST_SymbolRef, self, {
|
var ref = make_node(AST_SymbolRef, self, {
|
||||||
name : "undefined",
|
name : "undefined",
|
||||||
scope : scope,
|
scope : undef.scope,
|
||||||
thedef : undef
|
thedef : undef
|
||||||
});
|
});
|
||||||
ref.is_undefined = true;
|
ref.is_undefined = true;
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return self;
|
return make_node(AST_UnaryPrefix, self, {
|
||||||
|
operator: "void",
|
||||||
|
expression: make_node(AST_Number, self, {
|
||||||
|
value: 0
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
OPT(AST_Infinity, function(self, compressor){
|
||||||
|
var retain = compressor.option("keep_infinity") && !find_variable(compressor, "Infinity");
|
||||||
|
return retain ? self : make_node(AST_Binary, self, {
|
||||||
|
operator: "/",
|
||||||
|
left: make_node(AST_Number, self, {
|
||||||
|
value: 1
|
||||||
|
}),
|
||||||
|
right: make_node(AST_Number, self, {
|
||||||
|
value: 0
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
OPT(AST_NaN, function(self, compressor){
|
||||||
|
return find_variable(compressor, "NaN") ? make_node(AST_Binary, self, {
|
||||||
|
operator: "/",
|
||||||
|
left: make_node(AST_Number, self, {
|
||||||
|
value: 0
|
||||||
|
}),
|
||||||
|
right: make_node(AST_Number, self, {
|
||||||
|
value: 0
|
||||||
|
})
|
||||||
|
}) : self;
|
||||||
});
|
});
|
||||||
|
|
||||||
var ASSIGN_OPS = [ '+', '-', '/', '*', '%', '>>', '<<', '>>>', '|', '^', '&' ];
|
var ASSIGN_OPS = [ '+', '-', '/', '*', '%', '>>', '<<', '>>>', '|', '^', '&' ];
|
||||||
@@ -3809,7 +3870,7 @@ merge(Compressor.prototype, {
|
|||||||
OPT(AST_RegExp, literals_in_boolean_context);
|
OPT(AST_RegExp, literals_in_boolean_context);
|
||||||
|
|
||||||
OPT(AST_Return, function(self, compressor){
|
OPT(AST_Return, function(self, compressor){
|
||||||
if (self.value && is_undefined(self.value)) {
|
if (self.value && is_undefined(self.value, compressor)) {
|
||||||
self.value = null;
|
self.value = null;
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
|
|||||||
@@ -53,26 +53,26 @@ function is_some_comments(comment) {
|
|||||||
function OutputStream(options) {
|
function OutputStream(options) {
|
||||||
|
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
indent_start : 0,
|
|
||||||
indent_level : 4,
|
|
||||||
quote_keys : false,
|
|
||||||
space_colon : true,
|
|
||||||
ascii_only : false,
|
ascii_only : false,
|
||||||
unescape_regexps : false,
|
|
||||||
inline_script : false,
|
|
||||||
width : 80,
|
|
||||||
max_line_len : false,
|
|
||||||
beautify : false,
|
beautify : false,
|
||||||
source_map : null,
|
|
||||||
bracketize : false,
|
bracketize : false,
|
||||||
semicolons : true,
|
|
||||||
comments : false,
|
comments : false,
|
||||||
shebang : true,
|
indent_level : 4,
|
||||||
preserve_line : false,
|
indent_start : 0,
|
||||||
screw_ie8 : true,
|
inline_script : false,
|
||||||
preamble : null,
|
|
||||||
quote_style : 0,
|
|
||||||
keep_quoted_props: false,
|
keep_quoted_props: false,
|
||||||
|
max_line_len : false,
|
||||||
|
preamble : null,
|
||||||
|
preserve_line : false,
|
||||||
|
quote_keys : false,
|
||||||
|
quote_style : 0,
|
||||||
|
screw_ie8 : true,
|
||||||
|
semicolons : true,
|
||||||
|
shebang : true,
|
||||||
|
source_map : null,
|
||||||
|
space_colon : true,
|
||||||
|
unescape_regexps : false,
|
||||||
|
width : 80,
|
||||||
wrap_iife : false,
|
wrap_iife : false,
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
@@ -510,8 +510,8 @@ function OutputStream(options) {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (comments.length > 0 && output.pos() == 0) {
|
if (output.pos() == 0) {
|
||||||
if (output.option("shebang") && comments[0].type == "comment5") {
|
if (comments.length > 0 && output.option("shebang") && comments[0].type == "comment5") {
|
||||||
output.print("#!" + comments.shift().value + "\n");
|
output.print("#!" + comments.shift().value + "\n");
|
||||||
output.indent();
|
output.indent();
|
||||||
}
|
}
|
||||||
@@ -586,7 +586,7 @@ function OutputStream(options) {
|
|||||||
return first_in_statement(output);
|
return first_in_statement(output);
|
||||||
});
|
});
|
||||||
|
|
||||||
PARENS([ AST_Unary, AST_Undefined ], function(output){
|
PARENS(AST_Unary, function(output){
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
return p instanceof AST_PropAccess && p.expression === this
|
return p instanceof AST_PropAccess && p.expression === this
|
||||||
|| p instanceof AST_Call && p.expression === this;
|
|| p instanceof AST_Call && p.expression === this;
|
||||||
@@ -960,24 +960,24 @@ function OutputStream(options) {
|
|||||||
self.expression.print(output);
|
self.expression.print(output);
|
||||||
});
|
});
|
||||||
output.space();
|
output.space();
|
||||||
if (self.body.length > 0) output.with_block(function(){
|
var last = self.body.length - 1;
|
||||||
self.body.forEach(function(stmt, i){
|
if (last < 0) output.print("{}");
|
||||||
if (i) output.newline();
|
else output.with_block(function(){
|
||||||
|
self.body.forEach(function(branch, i){
|
||||||
output.indent(true);
|
output.indent(true);
|
||||||
stmt.print(output);
|
branch.print(output);
|
||||||
|
if (i < last && branch.body.length > 0)
|
||||||
|
output.newline();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
else output.print("{}");
|
|
||||||
});
|
});
|
||||||
AST_SwitchBranch.DEFMETHOD("_do_print_body", function(output){
|
AST_SwitchBranch.DEFMETHOD("_do_print_body", function(output){
|
||||||
if (this.body.length > 0) {
|
output.newline();
|
||||||
|
this.body.forEach(function(stmt){
|
||||||
|
output.indent();
|
||||||
|
stmt.print(output);
|
||||||
output.newline();
|
output.newline();
|
||||||
this.body.forEach(function(stmt){
|
});
|
||||||
output.indent();
|
|
||||||
stmt.print(output);
|
|
||||||
output.newline();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_Default, function(self, output){
|
DEFPRINT(AST_Default, function(self, output){
|
||||||
output.print("default:");
|
output.print("default:");
|
||||||
@@ -1249,16 +1249,7 @@ function OutputStream(options) {
|
|||||||
var def = self.definition();
|
var def = self.definition();
|
||||||
output.print_name(def ? def.mangled_name || def.name : self.name);
|
output.print_name(def ? def.mangled_name || def.name : self.name);
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_Undefined, function(self, output){
|
|
||||||
output.print("void 0");
|
|
||||||
});
|
|
||||||
DEFPRINT(AST_Hole, noop);
|
DEFPRINT(AST_Hole, noop);
|
||||||
DEFPRINT(AST_Infinity, function(self, output){
|
|
||||||
output.print("Infinity");
|
|
||||||
});
|
|
||||||
DEFPRINT(AST_NaN, function(self, output){
|
|
||||||
output.print("NaN");
|
|
||||||
});
|
|
||||||
DEFPRINT(AST_This, function(self, output){
|
DEFPRINT(AST_This, function(self, output){
|
||||||
output.print("this");
|
output.print("this");
|
||||||
});
|
});
|
||||||
|
|||||||
12
lib/parse.js
12
lib/parse.js
@@ -688,14 +688,14 @@ var ATOMIC_START_TOKEN = array_to_hash([ "atom", "num", "string", "regexp", "nam
|
|||||||
function parse($TEXT, options) {
|
function parse($TEXT, options) {
|
||||||
|
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
strict : false,
|
|
||||||
filename : null,
|
|
||||||
toplevel : null,
|
|
||||||
expression : false,
|
|
||||||
html5_comments : true,
|
|
||||||
bare_returns : false,
|
bare_returns : false,
|
||||||
shebang : true,
|
|
||||||
cli : false,
|
cli : false,
|
||||||
|
expression : false,
|
||||||
|
filename : null,
|
||||||
|
html5_comments : true,
|
||||||
|
shebang : true,
|
||||||
|
strict : false,
|
||||||
|
toplevel : null,
|
||||||
});
|
});
|
||||||
|
|
||||||
var S = {
|
var S = {
|
||||||
|
|||||||
@@ -62,12 +62,12 @@ function find_builtins() {
|
|||||||
|
|
||||||
function mangle_properties(ast, options) {
|
function mangle_properties(ast, options) {
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
reserved : null,
|
cache: null,
|
||||||
cache : null,
|
debug: false,
|
||||||
only_cache : false,
|
ignore_quoted: false,
|
||||||
regex : null,
|
only_cache: false,
|
||||||
ignore_quoted : false,
|
regex: null,
|
||||||
debug : false
|
reserved: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
var reserved = options.reserved;
|
var reserved = options.reserved;
|
||||||
|
|||||||
22
lib/scope.js
22
lib/scope.js
@@ -79,9 +79,7 @@ SymbolDef.prototype = {
|
|||||||
if (!options.screw_ie8 && sym instanceof AST_SymbolLambda)
|
if (!options.screw_ie8 && sym instanceof AST_SymbolLambda)
|
||||||
s = s.parent_scope;
|
s = s.parent_scope;
|
||||||
var def;
|
var def;
|
||||||
if (options.screw_ie8
|
if (this.defun && (def = this.defun.variables.get(this.name))) {
|
||||||
&& sym instanceof AST_SymbolCatch
|
|
||||||
&& (def = s.parent_scope.find_variable(sym))) {
|
|
||||||
this.mangled_name = def.mangled_name || def.name;
|
this.mangled_name = def.mangled_name || def.name;
|
||||||
} else
|
} else
|
||||||
this.mangled_name = s.next_mangled(options, this);
|
this.mangled_name = s.next_mangled(options, this);
|
||||||
@@ -94,8 +92,8 @@ SymbolDef.prototype = {
|
|||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
|
cache: null,
|
||||||
screw_ie8: true,
|
screw_ie8: true,
|
||||||
cache: null
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// pass 1: setup scope chaining and handle definitions
|
// pass 1: setup scope chaining and handle definitions
|
||||||
@@ -171,7 +169,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_SymbolCatch) {
|
else if (node instanceof AST_SymbolCatch) {
|
||||||
scope.def_variable(node);
|
scope.def_variable(node).defun = defun;
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_LabelRef) {
|
else if (node instanceof AST_LabelRef) {
|
||||||
var sym = labels.get(node.name);
|
var sym = labels.get(node.name);
|
||||||
@@ -227,7 +225,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
if (node instanceof AST_SymbolCatch) {
|
if (node instanceof AST_SymbolCatch) {
|
||||||
var name = node.name;
|
var name = node.name;
|
||||||
var refs = node.thedef.references;
|
var refs = node.thedef.references;
|
||||||
var scope = node.thedef.scope.parent_scope;
|
var scope = node.thedef.defun;
|
||||||
var def = scope.find_variable(name) || self.globals.get(name) || scope.def_variable(node);
|
var def = scope.find_variable(name) || self.globals.get(name) || scope.def_variable(node);
|
||||||
refs.forEach(function(ref) {
|
refs.forEach(function(ref) {
|
||||||
ref.thedef = def;
|
ref.thedef = def;
|
||||||
@@ -400,12 +398,12 @@ AST_Symbol.DEFMETHOD("global", function(){
|
|||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){
|
AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){
|
||||||
return defaults(options, {
|
return defaults(options, {
|
||||||
except : [],
|
|
||||||
eval : false,
|
eval : false,
|
||||||
|
except : [],
|
||||||
|
keep_fnames : false,
|
||||||
|
screw_ie8 : true,
|
||||||
sort : false, // Ignored. Flag retained for backwards compatibility.
|
sort : false, // Ignored. Flag retained for backwards compatibility.
|
||||||
toplevel : false,
|
toplevel : false,
|
||||||
screw_ie8 : true,
|
|
||||||
keep_fnames : false
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -578,12 +576,12 @@ var base54 = (function() {
|
|||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("scope_warnings", function(options){
|
AST_Toplevel.DEFMETHOD("scope_warnings", function(options){
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
undeclared : false, // this makes a lot of noise
|
|
||||||
unreferenced : true,
|
|
||||||
assign_to_global : true,
|
assign_to_global : true,
|
||||||
|
eval : true,
|
||||||
func_arguments : true,
|
func_arguments : true,
|
||||||
nested_defuns : true,
|
nested_defuns : true,
|
||||||
eval : true
|
undeclared : false, // this makes a lot of noise
|
||||||
|
unreferenced : true,
|
||||||
});
|
});
|
||||||
var tw = new TreeWalker(function(node){
|
var tw = new TreeWalker(function(node){
|
||||||
if (options.undeclared
|
if (options.undeclared
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"homepage": "http://lisperator.net/uglifyjs",
|
"homepage": "http://lisperator.net/uglifyjs",
|
||||||
"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": "2.8.17",
|
"version": "2.8.21",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -214,3 +214,45 @@ dead_code_const_annotation_complex_scope: {
|
|||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try_catch_finally: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
!function() {
|
||||||
|
try {
|
||||||
|
if (false) throw x;
|
||||||
|
} catch (a) {
|
||||||
|
var a = 2;
|
||||||
|
console.log("FAIL");
|
||||||
|
} finally {
|
||||||
|
a = 3;
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
try {
|
||||||
|
console.log(a);
|
||||||
|
} finally {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1;
|
||||||
|
!function() {
|
||||||
|
var a;
|
||||||
|
a = 3;
|
||||||
|
console.log("PASS");
|
||||||
|
}();
|
||||||
|
try {
|
||||||
|
console.log(a);
|
||||||
|
} finally {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS",
|
||||||
|
"1",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
@@ -853,7 +853,9 @@ issue_1715_1: {
|
|||||||
var a = 1;
|
var a = 1;
|
||||||
function f() {
|
function f() {
|
||||||
a++;
|
a++;
|
||||||
try {} catch (a) {
|
try {
|
||||||
|
x();
|
||||||
|
} catch (a) {
|
||||||
var a;
|
var a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -864,7 +866,9 @@ issue_1715_1: {
|
|||||||
var a = 1;
|
var a = 1;
|
||||||
function f() {
|
function f() {
|
||||||
a++;
|
a++;
|
||||||
try {} catch (a) {
|
try {
|
||||||
|
x();
|
||||||
|
} catch (a) {
|
||||||
var a;
|
var a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -882,7 +886,9 @@ issue_1715_2: {
|
|||||||
var a = 1;
|
var a = 1;
|
||||||
function f() {
|
function f() {
|
||||||
a++;
|
a++;
|
||||||
try {} catch (a) {
|
try {
|
||||||
|
x();
|
||||||
|
} catch (a) {
|
||||||
var a = 2;
|
var a = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -893,7 +899,9 @@ issue_1715_2: {
|
|||||||
var a = 1;
|
var a = 1;
|
||||||
function f() {
|
function f() {
|
||||||
a++;
|
a++;
|
||||||
try {} catch (a) {
|
try {
|
||||||
|
x();
|
||||||
|
} catch (a) {
|
||||||
var a;
|
var a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -911,7 +919,9 @@ issue_1715_3: {
|
|||||||
var a = 1;
|
var a = 1;
|
||||||
function f() {
|
function f() {
|
||||||
a++;
|
a++;
|
||||||
try {} catch (a) {
|
try {
|
||||||
|
console;
|
||||||
|
} catch (a) {
|
||||||
var a = 2 + x();
|
var a = 2 + x();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -922,7 +932,9 @@ issue_1715_3: {
|
|||||||
var a = 1;
|
var a = 1;
|
||||||
function f() {
|
function f() {
|
||||||
a++;
|
a++;
|
||||||
try {} catch (a) {
|
try {
|
||||||
|
console;
|
||||||
|
} catch (a) {
|
||||||
var a = x();
|
var a = x();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -931,3 +943,34 @@ issue_1715_3: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "1"
|
expect_stdout: "1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_1715_4: {
|
||||||
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
!function a() {
|
||||||
|
a++;
|
||||||
|
try {
|
||||||
|
x();
|
||||||
|
} catch (a) {
|
||||||
|
var a;
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1;
|
||||||
|
!function() {
|
||||||
|
a++;
|
||||||
|
try {
|
||||||
|
x();
|
||||||
|
} catch (a) {
|
||||||
|
var a;
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|||||||
@@ -196,8 +196,8 @@ negative_zero: {
|
|||||||
console.log(
|
console.log(
|
||||||
-0,
|
-0,
|
||||||
0,
|
0,
|
||||||
1 / (-0),
|
-1/0,
|
||||||
1 / (-0)
|
-1/0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
@@ -217,8 +217,8 @@ positive_zero: {
|
|||||||
console.log(
|
console.log(
|
||||||
0,
|
0,
|
||||||
-0,
|
-0,
|
||||||
1 / (0),
|
1/0,
|
||||||
1 / (0)
|
1/0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
@@ -802,3 +802,58 @@ issue_1649: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "-2";
|
expect_stdout: "-2";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_1760_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function(a) {
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (NaN) {
|
||||||
|
a = +"foo";
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function(a) {
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (NaN) {
|
||||||
|
a = 0 / 0;
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "NaN"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1760_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
keep_infinity: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function(a) {
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (Infinity) {
|
||||||
|
a = 123456789 / 0;
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function(a) {
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (Infinity) {
|
||||||
|
a = 1 / 0;
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "Infinity"
|
||||||
|
}
|
||||||
|
|||||||
@@ -193,13 +193,15 @@ assorted_Infinity_NaN_undefined_in_with_scope: {
|
|||||||
cascade: true,
|
cascade: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
sequences: false,
|
sequences: false,
|
||||||
|
keep_infinity: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
var f = console.log;
|
||||||
var o = {
|
var o = {
|
||||||
undefined : 3,
|
undefined : 3,
|
||||||
NaN : 4,
|
NaN : 4,
|
||||||
Infinity : 5,
|
Infinity : 5,
|
||||||
}
|
};
|
||||||
if (o) {
|
if (o) {
|
||||||
f(undefined, void 0);
|
f(undefined, void 0);
|
||||||
f(NaN, 0/0);
|
f(NaN, 0/0);
|
||||||
@@ -216,25 +218,88 @@ assorted_Infinity_NaN_undefined_in_with_scope: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var o = {
|
var f = console.log, o = {
|
||||||
undefined : 3,
|
undefined : 3,
|
||||||
NaN : 4,
|
NaN : 4,
|
||||||
Infinity : 5
|
Infinity : 5
|
||||||
}
|
};
|
||||||
if (o) {
|
if (o) {
|
||||||
f(void 0, void 0);
|
f(void 0, void 0);
|
||||||
f(NaN, NaN);
|
f(NaN, NaN);
|
||||||
f(1/0, 1/0);
|
f(1/0, 1/0);
|
||||||
f(-(1/0), -(1/0));
|
f(-1/0, -1/0);
|
||||||
f(NaN, NaN);
|
f(NaN, NaN);
|
||||||
}
|
}
|
||||||
with (o) {
|
with (o) {
|
||||||
f(undefined, void 0);
|
f(undefined, void 0);
|
||||||
f(NaN, 0/0);
|
f(NaN, 0/0);
|
||||||
f(Infinity, 1/0);
|
f(Infinity, 1/0);
|
||||||
f(-Infinity, -(1/0));
|
f(-Infinity, -1/0);
|
||||||
f(9 + undefined, 9 + void 0);
|
f(9 + undefined, 9 + void 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assorted_Infinity_NaN_undefined_in_with_scope_keep_infinity: {
|
||||||
|
options = {
|
||||||
|
unused: true,
|
||||||
|
evaluate: true,
|
||||||
|
dead_code: true,
|
||||||
|
conditionals: true,
|
||||||
|
comparisons: true,
|
||||||
|
booleans: true,
|
||||||
|
hoist_funs: true,
|
||||||
|
keep_fargs: true,
|
||||||
|
if_return: true,
|
||||||
|
join_vars: true,
|
||||||
|
cascade: true,
|
||||||
|
side_effects: true,
|
||||||
|
sequences: false,
|
||||||
|
keep_infinity: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var f = console.log;
|
||||||
|
var o = {
|
||||||
|
undefined : 3,
|
||||||
|
NaN : 4,
|
||||||
|
Infinity : 5,
|
||||||
|
};
|
||||||
|
if (o) {
|
||||||
|
f(undefined, void 0);
|
||||||
|
f(NaN, 0/0);
|
||||||
|
f(Infinity, 1/0);
|
||||||
|
f(-Infinity, -(1/0));
|
||||||
|
f(2 + 7 + undefined, 2 + 7 + void 0);
|
||||||
|
}
|
||||||
|
with (o) {
|
||||||
|
f(undefined, void 0);
|
||||||
|
f(NaN, 0/0);
|
||||||
|
f(Infinity, 1/0);
|
||||||
|
f(-Infinity, -(1/0));
|
||||||
|
f(2 + 7 + undefined, 2 + 7 + void 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var f = console.log, o = {
|
||||||
|
undefined : 3,
|
||||||
|
NaN : 4,
|
||||||
|
Infinity : 5
|
||||||
|
};
|
||||||
|
if (o) {
|
||||||
|
f(void 0, void 0);
|
||||||
|
f(NaN, NaN);
|
||||||
|
f(Infinity, 1/0);
|
||||||
|
f(-Infinity, -1/0);
|
||||||
|
f(NaN, NaN);
|
||||||
|
}
|
||||||
|
with (o) {
|
||||||
|
f(undefined, void 0);
|
||||||
|
f(NaN, 0/0);
|
||||||
|
f(Infinity, 1/0);
|
||||||
|
f(-Infinity, -1/0);
|
||||||
|
f(9 + undefined, 9 + void 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|||||||
@@ -154,12 +154,12 @@ should_warn: {
|
|||||||
"WARN: Boolean || always true [test/compress/issue-1261.js:129,23]",
|
"WARN: Boolean || always true [test/compress/issue-1261.js:129,23]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:129,23]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:129,23]",
|
||||||
"WARN: Condition always true [test/compress/issue-1261.js:129,23]",
|
"WARN: Condition always true [test/compress/issue-1261.js:129,23]",
|
||||||
"WARN: Boolean || always true [test/compress/issue-1261.js:130,8]",
|
"WARN: Condition left of || always true [test/compress/issue-1261.js:130,8]",
|
||||||
"WARN: Condition always true [test/compress/issue-1261.js:130,8]",
|
"WARN: Condition always true [test/compress/issue-1261.js:130,8]",
|
||||||
"WARN: Boolean && always false [test/compress/issue-1261.js:131,23]",
|
"WARN: Boolean && always false [test/compress/issue-1261.js:131,23]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:131,23]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:131,23]",
|
||||||
"WARN: Condition always false [test/compress/issue-1261.js:131,23]",
|
"WARN: Condition always false [test/compress/issue-1261.js:131,23]",
|
||||||
"WARN: Boolean && always false [test/compress/issue-1261.js:132,8]",
|
"WARN: Condition left of && always false [test/compress/issue-1261.js:132,8]",
|
||||||
"WARN: Condition always false [test/compress/issue-1261.js:132,8]",
|
"WARN: Condition always false [test/compress/issue-1261.js:132,8]",
|
||||||
"WARN: + in boolean context always true [test/compress/issue-1261.js:133,23]",
|
"WARN: + in boolean context always true [test/compress/issue-1261.js:133,23]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:133,23]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:133,23]",
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ side_effects_finally: {
|
|||||||
function f() {
|
function f() {
|
||||||
function g() {
|
function g() {
|
||||||
try {
|
try {
|
||||||
|
x();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
} finally {
|
} finally {
|
||||||
console.log("PASS");
|
console.log("PASS");
|
||||||
@@ -83,6 +84,7 @@ side_effects_finally: {
|
|||||||
function f() {
|
function f() {
|
||||||
(function() {
|
(function() {
|
||||||
try {
|
try {
|
||||||
|
x();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
} finally {
|
} finally {
|
||||||
console.log("PASS");
|
console.log("PASS");
|
||||||
|
|||||||
97
test/compress/issue-1733.js
Normal file
97
test/compress/issue-1733.js
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
function_iife_catch: {
|
||||||
|
mangle = {
|
||||||
|
screw_ie8: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(n) {
|
||||||
|
!function() {
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (n) {
|
||||||
|
var a = 1;
|
||||||
|
console.log(n, a);
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect_exact: "function f(o){!function(){try{throw 0}catch(c){var o=1;console.log(c,o)}}()}f();"
|
||||||
|
expect_stdout: "0 1"
|
||||||
|
}
|
||||||
|
|
||||||
|
function_iife_catch_ie8: {
|
||||||
|
mangle = {
|
||||||
|
screw_ie8: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(n) {
|
||||||
|
!function() {
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (n) {
|
||||||
|
var a = 1;
|
||||||
|
console.log(n, a);
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect_exact: "function f(o){!function(){try{throw 0}catch(o){var c=1;console.log(o,c)}}()}f();"
|
||||||
|
expect_stdout: "0 1"
|
||||||
|
}
|
||||||
|
|
||||||
|
function_catch_catch: {
|
||||||
|
mangle = {
|
||||||
|
screw_ie8: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = 0;
|
||||||
|
function f() {
|
||||||
|
try {
|
||||||
|
throw 1;
|
||||||
|
} catch (c) {
|
||||||
|
try {
|
||||||
|
throw 2;
|
||||||
|
} catch (o) {
|
||||||
|
var o = 3;
|
||||||
|
console.log(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(o);
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect_exact: "var o=0;function f(){try{throw 1}catch(c){try{throw 2}catch(o){var o=3;console.log(o)}}console.log(o)}f();"
|
||||||
|
expect_stdout: [
|
||||||
|
"3",
|
||||||
|
"undefined",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
function_catch_catch_ie8: {
|
||||||
|
mangle = {
|
||||||
|
screw_ie8: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = 0;
|
||||||
|
function f() {
|
||||||
|
try {
|
||||||
|
throw 1;
|
||||||
|
} catch (c) {
|
||||||
|
try {
|
||||||
|
throw 2;
|
||||||
|
} catch (o) {
|
||||||
|
var o = 3;
|
||||||
|
console.log(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(o);
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect_exact: "var o=0;function f(){try{throw 1}catch(c){try{throw 2}catch(o){var o=3;console.log(o)}}console.log(o)}f();"
|
||||||
|
expect_stdout: [
|
||||||
|
"3",
|
||||||
|
"undefined",
|
||||||
|
]
|
||||||
|
}
|
||||||
54
test/compress/issue-1750.js
Normal file
54
test/compress/issue-1750.js
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
case_1: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0, b = 1;
|
||||||
|
switch (true) {
|
||||||
|
case a, true:
|
||||||
|
default:
|
||||||
|
b = 2;
|
||||||
|
case true:
|
||||||
|
}
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0, b = 1;
|
||||||
|
switch (true) {
|
||||||
|
case a, true:
|
||||||
|
b = 2;
|
||||||
|
}
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect_stdout: "0 2"
|
||||||
|
}
|
||||||
|
|
||||||
|
case_2: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0, b = 1;
|
||||||
|
switch (0) {
|
||||||
|
default:
|
||||||
|
b = 2;
|
||||||
|
case a:
|
||||||
|
a = 3;
|
||||||
|
case 0:
|
||||||
|
}
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0, b = 1;
|
||||||
|
switch (0) {
|
||||||
|
case a:
|
||||||
|
a = 3;
|
||||||
|
}
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect_stdout: "3 1"
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ NaN_and_Infinity_must_have_parens: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
(1/0).toString();
|
(1/0).toString();
|
||||||
NaN.toString(); // transformation to 0/0 dropped
|
NaN.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,3 +23,135 @@ NaN_and_Infinity_should_not_be_replaced_when_they_are_redefined: {
|
|||||||
NaN.toString();
|
NaN.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NaN_and_Infinity_must_have_parens_evaluate: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(123456789 / 0).toString();
|
||||||
|
(+"foo").toString();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(1/0).toString();
|
||||||
|
NaN.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NaN_and_Infinity_should_not_be_replaced_when_they_are_redefined_evaluate: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var Infinity, NaN;
|
||||||
|
(123456789 / 0).toString();
|
||||||
|
(+"foo").toString();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var Infinity, NaN;
|
||||||
|
(1/0).toString();
|
||||||
|
(0/0).toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
beautify_off_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
beautify: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var NaN;
|
||||||
|
console.log(
|
||||||
|
null,
|
||||||
|
undefined,
|
||||||
|
Infinity,
|
||||||
|
NaN,
|
||||||
|
Infinity * undefined,
|
||||||
|
Infinity.toString(),
|
||||||
|
NaN.toString(),
|
||||||
|
(Infinity * undefined).toString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
expect_exact: "var NaN;console.log(null,void 0,1/0,NaN,0/0,(1/0).toString(),NaN.toString(),(0/0).toString());"
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
beautify_off_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
beautify: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(
|
||||||
|
null.toString(),
|
||||||
|
undefined.toString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
expect_exact: "console.log(null.toString(),(void 0).toString());"
|
||||||
|
}
|
||||||
|
|
||||||
|
beautify_on_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
beautify: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var NaN;
|
||||||
|
console.log(
|
||||||
|
null,
|
||||||
|
undefined,
|
||||||
|
Infinity,
|
||||||
|
NaN,
|
||||||
|
Infinity * undefined,
|
||||||
|
Infinity.toString(),
|
||||||
|
NaN.toString(),
|
||||||
|
(Infinity * undefined).toString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"var NaN;",
|
||||||
|
"",
|
||||||
|
"console.log(null, void 0, 1 / 0, NaN, 0 / 0, (1 / 0).toString(), NaN.toString(), (0 / 0).toString());",
|
||||||
|
]
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
beautify_on_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
beautify: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(
|
||||||
|
null.toString(),
|
||||||
|
undefined.toString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
expect_exact: "console.log(null.toString(), (void 0).toString());"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1724: {
|
||||||
|
input: {
|
||||||
|
var a = 0;
|
||||||
|
++a % Infinity | Infinity ? a++ : 0;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_exact: "var a=0;++a%(1/0)|1/0?a++:0;console.log(a);"
|
||||||
|
expect_stdout: "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1725: {
|
||||||
|
input: {
|
||||||
|
([].length === 0) % Infinity ? console.log("PASS") : console.log("FAIL");
|
||||||
|
}
|
||||||
|
expect_exact: '(0===[].length)%(1/0)?console.log("PASS"):console.log("FAIL");'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -168,3 +168,37 @@ issue_1710: {
|
|||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unary_binary_parenthesis: {
|
||||||
|
input: {
|
||||||
|
var v = [ 0, 1, NaN, Infinity, null, undefined, true, false, "", "foo", /foo/ ];
|
||||||
|
v.forEach(function(x) {
|
||||||
|
v.forEach(function(y) {
|
||||||
|
console.log(
|
||||||
|
+(x*y),
|
||||||
|
+(x/y),
|
||||||
|
+(x%y),
|
||||||
|
-(x*y),
|
||||||
|
-(x/y),
|
||||||
|
-(x%y)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var v = [ 0, 1, NaN, 1/0, null, void 0, true, false, "", "foo", /foo/ ];
|
||||||
|
v.forEach(function(x) {
|
||||||
|
v.forEach(function(y) {
|
||||||
|
console.log(
|
||||||
|
+x*y,
|
||||||
|
+x/y,
|
||||||
|
+x%y,
|
||||||
|
-x*y,
|
||||||
|
-x/y,
|
||||||
|
-x%y
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|||||||
@@ -1399,6 +1399,8 @@ issue_1670_1: {
|
|||||||
evaluate: true,
|
evaluate: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -1429,6 +1431,8 @@ issue_1670_2: {
|
|||||||
dead_code: true,
|
dead_code: true,
|
||||||
passes: 2,
|
passes: 2,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -1458,6 +1462,8 @@ issue_1670_3: {
|
|||||||
evaluate: true,
|
evaluate: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -1488,6 +1494,8 @@ issue_1670_4: {
|
|||||||
dead_code: true,
|
dead_code: true,
|
||||||
passes: 2,
|
passes: 2,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -1516,6 +1524,8 @@ issue_1670_5: {
|
|||||||
evaluate: true,
|
evaluate: true,
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -1544,6 +1554,8 @@ issue_1670_6: {
|
|||||||
evaluate: true,
|
evaluate: true,
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|||||||
@@ -204,13 +204,13 @@ issue_1586_1: {
|
|||||||
input: {
|
input: {
|
||||||
function f() {
|
function f() {
|
||||||
try {
|
try {
|
||||||
|
x();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err.message);
|
console.log(err.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_exact: "function f(){try{}catch(c){console.log(c.message)}}"
|
expect_exact: "function f(){try{x()}catch(c){console.log(c.message)}}"
|
||||||
expect_stdout: true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_1586_2: {
|
issue_1586_2: {
|
||||||
@@ -223,11 +223,11 @@ issue_1586_2: {
|
|||||||
input: {
|
input: {
|
||||||
function f() {
|
function f() {
|
||||||
try {
|
try {
|
||||||
|
x();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err.message);
|
console.log(err.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_exact: "function f(){try{}catch(c){console.log(c.message)}}"
|
expect_exact: "function f(){try{x()}catch(c){console.log(c.message)}}"
|
||||||
expect_stdout: true
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -440,3 +440,29 @@ func_def_5: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "true"
|
expect_stdout: "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_1758: {
|
||||||
|
options = {
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(c) {
|
||||||
|
var undefined = 42;
|
||||||
|
return function() {
|
||||||
|
c--;
|
||||||
|
c--, c.toString();
|
||||||
|
return;
|
||||||
|
}();
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(c) {
|
||||||
|
var undefined = 42;
|
||||||
|
return function() {
|
||||||
|
return c--, c--, c.toString(), void 0;
|
||||||
|
}();
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
constant_switch_1: {
|
constant_switch_1: {
|
||||||
options = { dead_code: true, evaluate: true };
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (1+1) {
|
switch (1+1) {
|
||||||
case 1: foo(); break;
|
case 1: foo(); break;
|
||||||
@@ -13,7 +18,12 @@ constant_switch_1: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constant_switch_2: {
|
constant_switch_2: {
|
||||||
options = { dead_code: true, evaluate: true };
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (1) {
|
switch (1) {
|
||||||
case 1: foo();
|
case 1: foo();
|
||||||
@@ -28,7 +38,12 @@ constant_switch_2: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constant_switch_3: {
|
constant_switch_3: {
|
||||||
options = { dead_code: true, evaluate: true };
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (10) {
|
switch (10) {
|
||||||
case 1: foo();
|
case 1: foo();
|
||||||
@@ -44,7 +59,12 @@ constant_switch_3: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constant_switch_4: {
|
constant_switch_4: {
|
||||||
options = { dead_code: true, evaluate: true };
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (2) {
|
switch (2) {
|
||||||
case 1:
|
case 1:
|
||||||
@@ -65,7 +85,12 @@ constant_switch_4: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constant_switch_5: {
|
constant_switch_5: {
|
||||||
options = { dead_code: true, evaluate: true };
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (1) {
|
switch (1) {
|
||||||
case 1:
|
case 1:
|
||||||
@@ -94,7 +119,12 @@ constant_switch_5: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constant_switch_6: {
|
constant_switch_6: {
|
||||||
options = { dead_code: true, evaluate: true };
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
OUT: {
|
OUT: {
|
||||||
foo();
|
foo();
|
||||||
@@ -123,7 +153,12 @@ constant_switch_6: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constant_switch_7: {
|
constant_switch_7: {
|
||||||
options = { dead_code: true, evaluate: true };
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
OUT: {
|
OUT: {
|
||||||
foo();
|
foo();
|
||||||
@@ -161,7 +196,12 @@ constant_switch_7: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constant_switch_8: {
|
constant_switch_8: {
|
||||||
options = { dead_code: true, evaluate: true };
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
OUT: switch (1) {
|
OUT: switch (1) {
|
||||||
case 1:
|
case 1:
|
||||||
@@ -185,7 +225,12 @@ constant_switch_8: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constant_switch_9: {
|
constant_switch_9: {
|
||||||
options = { dead_code: true, evaluate: true };
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
OUT: switch (1) {
|
OUT: switch (1) {
|
||||||
case 1:
|
case 1:
|
||||||
@@ -210,7 +255,10 @@ constant_switch_9: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
drop_default_1: {
|
drop_default_1: {
|
||||||
options = { dead_code: true };
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (foo) {
|
switch (foo) {
|
||||||
case 'bar': baz();
|
case 'bar': baz();
|
||||||
@@ -225,7 +273,10 @@ drop_default_1: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
drop_default_2: {
|
drop_default_2: {
|
||||||
options = { dead_code: true };
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (foo) {
|
switch (foo) {
|
||||||
case 'bar': baz(); break;
|
case 'bar': baz(); break;
|
||||||
@@ -241,7 +292,10 @@ drop_default_2: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
keep_default: {
|
keep_default: {
|
||||||
options = { dead_code: true };
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (foo) {
|
switch (foo) {
|
||||||
case 'bar': baz();
|
case 'bar': baz();
|
||||||
@@ -263,6 +317,8 @@ issue_1663: {
|
|||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = 100, b = 10;
|
var a = 100, b = 10;
|
||||||
@@ -294,6 +350,7 @@ issue_1663: {
|
|||||||
drop_case: {
|
drop_case: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (foo) {
|
switch (foo) {
|
||||||
@@ -312,6 +369,7 @@ drop_case: {
|
|||||||
keep_case: {
|
keep_case: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (foo) {
|
switch (foo) {
|
||||||
@@ -332,6 +390,7 @@ issue_376: {
|
|||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (true) {
|
switch (true) {
|
||||||
@@ -354,6 +413,7 @@ issue_376: {
|
|||||||
issue_441_1: {
|
issue_441_1: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (foo) {
|
switch (foo) {
|
||||||
@@ -381,6 +441,7 @@ issue_441_1: {
|
|||||||
issue_441_2: {
|
issue_441_2: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (foo) {
|
switch (foo) {
|
||||||
@@ -414,6 +475,8 @@ issue_1674: {
|
|||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (0) {
|
switch (0) {
|
||||||
@@ -435,6 +498,7 @@ issue_1679: {
|
|||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = 100, b = 10;
|
var a = 100, b = 10;
|
||||||
@@ -482,6 +546,7 @@ issue_1680_1: {
|
|||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(x) {
|
function f(x) {
|
||||||
@@ -522,6 +587,7 @@ issue_1680_1: {
|
|||||||
issue_1680_2: {
|
issue_1680_2: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = 100, b = 10;
|
var a = 100, b = 10;
|
||||||
@@ -557,6 +623,7 @@ issue_1680_2: {
|
|||||||
issue_1690_1: {
|
issue_1690_1: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (console.log("PASS")) {}
|
switch (console.log("PASS")) {}
|
||||||
@@ -570,6 +637,7 @@ issue_1690_1: {
|
|||||||
issue_1690_2: {
|
issue_1690_2: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: false,
|
dead_code: false,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (console.log("PASS")) {}
|
switch (console.log("PASS")) {}
|
||||||
@@ -585,6 +653,7 @@ if_switch_typeof: {
|
|||||||
conditionals: true,
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
if (a) switch(typeof b) {}
|
if (a) switch(typeof b) {}
|
||||||
@@ -597,6 +666,7 @@ if_switch_typeof: {
|
|||||||
issue_1698: {
|
issue_1698: {
|
||||||
options = {
|
options = {
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = 1;
|
var a = 1;
|
||||||
@@ -618,6 +688,7 @@ issue_1698: {
|
|||||||
issue_1705_1: {
|
issue_1705_1: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = 0;
|
var a = 0;
|
||||||
@@ -646,6 +717,7 @@ issue_1705_2: {
|
|||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -666,6 +738,7 @@ issue_1705_2: {
|
|||||||
issue_1705_3: {
|
issue_1705_3: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (a) {
|
switch (a) {
|
||||||
@@ -680,3 +753,66 @@ issue_1705_3: {
|
|||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
beautify: {
|
||||||
|
beautify = {
|
||||||
|
beautify: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
switch (a) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
switch (b) {
|
||||||
|
case 3:
|
||||||
|
foo();
|
||||||
|
bar();
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"switch (a) {",
|
||||||
|
" case 0:",
|
||||||
|
" case 1:",
|
||||||
|
" break;",
|
||||||
|
"",
|
||||||
|
" case 2:",
|
||||||
|
" default:",
|
||||||
|
"}",
|
||||||
|
"",
|
||||||
|
"switch (b) {",
|
||||||
|
" case 3:",
|
||||||
|
" foo();",
|
||||||
|
" bar();",
|
||||||
|
"",
|
||||||
|
" default:",
|
||||||
|
" break;",
|
||||||
|
"}",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1758: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1, b = 2;
|
||||||
|
switch (a--) {
|
||||||
|
default:
|
||||||
|
b++;
|
||||||
|
}
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1, b = 2;
|
||||||
|
a--;
|
||||||
|
b++;
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect_stdout: "0 3"
|
||||||
|
}
|
||||||
|
|||||||
@@ -79,5 +79,13 @@ describe("comment filters", function() {
|
|||||||
output: { preamble: "/* Build */" }
|
output: { preamble: "/* Build */" }
|
||||||
}).code;
|
}).code;
|
||||||
assert.strictEqual(code, "#!/usr/bin/node\n/* Build */\nvar x=10;");
|
assert.strictEqual(code, "#!/usr/bin/node\n/* Build */\nvar x=10;");
|
||||||
})
|
});
|
||||||
|
|
||||||
|
it("Should handle preamble without shebang correctly", function() {
|
||||||
|
var code = UglifyJS.minify("var x = 10;", {
|
||||||
|
fromString: true,
|
||||||
|
output: { preamble: "/* Build */" }
|
||||||
|
}).code;
|
||||||
|
assert.strictEqual(code, "/* Build */\nvar x=10;");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ describe("Directives", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Should test EXPECT_DIRECTIVE RegExp", function() {
|
it("Should test EXPECT_DIRECTIVE RegExp", function() {
|
||||||
var tests = [
|
[
|
||||||
["", true],
|
["", true],
|
||||||
["'test';", true],
|
["'test';", true],
|
||||||
["'test';;", true],
|
["'test';;", true],
|
||||||
@@ -185,11 +185,12 @@ describe("Directives", function() {
|
|||||||
["'tests'; \n\t", true],
|
["'tests'; \n\t", true],
|
||||||
["'tests';\n\n", true],
|
["'tests';\n\n", true],
|
||||||
["\n\n\"use strict\";\n\n", true]
|
["\n\n\"use strict\";\n\n", true]
|
||||||
];
|
].forEach(function(test) {
|
||||||
|
var out = uglify.OutputStream();
|
||||||
for (var i = 0; i < tests.length; i++) {
|
out.print(test[0]);
|
||||||
assert.strictEqual(uglify.EXPECT_DIRECTIVE.test(tests[i][0]), tests[i][1], tests[i][0]);
|
out.print_string("", null, true);
|
||||||
}
|
assert.strictEqual(out.get() === test[0] + ';""', test[1], test[0]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should only print 2 semicolons spread over 2 lines in beautify mode", function() {
|
it("Should only print 2 semicolons spread over 2 lines in beautify mode", function() {
|
||||||
|
|||||||
@@ -1,27 +1,14 @@
|
|||||||
#! /usr/bin/env node
|
#! /usr/bin/env node
|
||||||
|
|
||||||
global.UGLIFY_DEBUG = true;
|
|
||||||
|
|
||||||
var U = require("../tools/node");
|
var U = require("../tools/node");
|
||||||
var path = require("path");
|
var path = require("path");
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var vm = require("vm");
|
var sandbox = require("./sandbox");
|
||||||
|
|
||||||
var tests_dir = path.dirname(module.filename);
|
var tests_dir = path.dirname(module.filename);
|
||||||
var failures = 0;
|
var failures = 0;
|
||||||
var failed_files = {};
|
var failed_files = {};
|
||||||
var same_stdout = ~process.version.lastIndexOf("v0.12.", 0) ? function(expected, actual) {
|
|
||||||
if (typeof expected != typeof actual) return false;
|
|
||||||
if (typeof expected != "string") {
|
|
||||||
if (expected.name != actual.name) return false;
|
|
||||||
expected = expected.message.slice(expected.message.lastIndexOf("\n") + 1);
|
|
||||||
actual = actual.message.slice(actual.message.lastIndexOf("\n") + 1);
|
|
||||||
}
|
|
||||||
return expected == actual;
|
|
||||||
} : function(expected, actual) {
|
|
||||||
return typeof expected == typeof actual && expected.toString() == actual.toString();
|
|
||||||
};
|
|
||||||
|
|
||||||
run_compress_tests();
|
run_compress_tests();
|
||||||
if (failures) {
|
if (failures) {
|
||||||
@@ -184,11 +171,11 @@ function run_compress_tests() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (test.expect_stdout) {
|
if (test.expect_stdout) {
|
||||||
var stdout = run_code(input_code);
|
var stdout = sandbox.run_code(input_code);
|
||||||
if (test.expect_stdout === true) {
|
if (test.expect_stdout === true) {
|
||||||
test.expect_stdout = stdout;
|
test.expect_stdout = stdout;
|
||||||
}
|
}
|
||||||
if (!same_stdout(test.expect_stdout, stdout)) {
|
if (!sandbox.same_stdout(test.expect_stdout, stdout)) {
|
||||||
log("!!! Invalid input or expected stdout\n---INPUT---\n{input}\n---EXPECTED {expected_type}---\n{expected}\n---ACTUAL {actual_type}---\n{actual}\n\n", {
|
log("!!! Invalid input or expected stdout\n---INPUT---\n{input}\n---EXPECTED {expected_type}---\n{expected}\n---ACTUAL {actual_type}---\n{actual}\n\n", {
|
||||||
input: input_formatted,
|
input: input_formatted,
|
||||||
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
|
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
|
||||||
@@ -199,8 +186,8 @@ function run_compress_tests() {
|
|||||||
failures++;
|
failures++;
|
||||||
failed_files[file] = 1;
|
failed_files[file] = 1;
|
||||||
} else {
|
} else {
|
||||||
stdout = run_code(output);
|
stdout = sandbox.run_code(output);
|
||||||
if (!same_stdout(test.expect_stdout, stdout)) {
|
if (!sandbox.same_stdout(test.expect_stdout, stdout)) {
|
||||||
log("!!! failed\n---INPUT---\n{input}\n---EXPECTED {expected_type}---\n{expected}\n---ACTUAL {actual_type}---\n{actual}\n\n", {
|
log("!!! failed\n---INPUT---\n{input}\n---EXPECTED {expected_type}---\n{expected}\n---ACTUAL {actual_type}---\n{actual}\n\n", {
|
||||||
input: input_formatted,
|
input: input_formatted,
|
||||||
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
|
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
|
||||||
@@ -332,19 +319,3 @@ function evaluate(code) {
|
|||||||
code = make_code(code, { beautify: true });
|
code = make_code(code, { beautify: true });
|
||||||
return new Function("return(" + code + ")")();
|
return new Function("return(" + code + ")")();
|
||||||
}
|
}
|
||||||
|
|
||||||
function run_code(code) {
|
|
||||||
var stdout = "";
|
|
||||||
var original_write = process.stdout.write;
|
|
||||||
process.stdout.write = function(chunk) {
|
|
||||||
stdout += chunk;
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
new vm.Script(code).runInNewContext({ console: console }, { timeout: 5000 });
|
|
||||||
return stdout;
|
|
||||||
} catch (ex) {
|
|
||||||
return ex;
|
|
||||||
} finally {
|
|
||||||
process.stdout.write = original_write;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
50
test/sandbox.js
Normal file
50
test/sandbox.js
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
var vm = require("vm");
|
||||||
|
|
||||||
|
var FUNC_TOSTRING = [
|
||||||
|
"Function.prototype.toString = Function.prototype.valueOf = function() {",
|
||||||
|
" var ids = [];",
|
||||||
|
" return function() {",
|
||||||
|
" var i = ids.indexOf(this);",
|
||||||
|
" if (i < 0) {",
|
||||||
|
" i = ids.length;",
|
||||||
|
" ids.push(this);",
|
||||||
|
" }",
|
||||||
|
' return "[Function: __func_" + i + "__]";',
|
||||||
|
" }",
|
||||||
|
"}();",
|
||||||
|
""
|
||||||
|
].join("\n");
|
||||||
|
exports.run_code = function(code) {
|
||||||
|
var stdout = "";
|
||||||
|
var original_write = process.stdout.write;
|
||||||
|
process.stdout.write = function(chunk) {
|
||||||
|
stdout += chunk;
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
new vm.Script(FUNC_TOSTRING + code).runInNewContext({
|
||||||
|
console: {
|
||||||
|
log: function() {
|
||||||
|
return console.log.apply(console, [].map.call(arguments, function(arg) {
|
||||||
|
return typeof arg == "function" ? arg.toString() : arg;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, { timeout: 30000 });
|
||||||
|
return stdout;
|
||||||
|
} catch (ex) {
|
||||||
|
return ex;
|
||||||
|
} finally {
|
||||||
|
process.stdout.write = original_write;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
exports.same_stdout = ~process.version.lastIndexOf("v0.12.", 0) ? function(expected, actual) {
|
||||||
|
if (typeof expected != typeof actual) return false;
|
||||||
|
if (typeof expected != "string") {
|
||||||
|
if (expected.name != actual.name) return false;
|
||||||
|
expected = expected.message.slice(expected.message.lastIndexOf("\n") + 1);
|
||||||
|
actual = actual.message.slice(actual.message.lastIndexOf("\n") + 1);
|
||||||
|
}
|
||||||
|
return expected == actual;
|
||||||
|
} : function(expected, actual) {
|
||||||
|
return typeof expected == typeof actual && expected.toString() == actual.toString();
|
||||||
|
};
|
||||||
1097
test/ufuzz.js
1097
test/ufuzz.js
File diff suppressed because it is too large
Load Diff
33
test/ufuzz.json
Normal file
33
test/ufuzz.json
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"compress": {
|
||||||
|
"warnings": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"compress": {
|
||||||
|
"warnings": false
|
||||||
|
},
|
||||||
|
"mangle": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"compress": false,
|
||||||
|
"mangle": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"compress": false,
|
||||||
|
"mangle": false,
|
||||||
|
"output": {
|
||||||
|
"beautify": true,
|
||||||
|
"bracketize": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"compress": {
|
||||||
|
"keep_fargs": false,
|
||||||
|
"passes": 3,
|
||||||
|
"pure_getters": true,
|
||||||
|
"warnings": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -17,7 +17,3 @@ exports["string_template"] = string_template;
|
|||||||
exports["tokenizer"] = tokenizer;
|
exports["tokenizer"] = tokenizer;
|
||||||
exports["is_identifier"] = is_identifier;
|
exports["is_identifier"] = is_identifier;
|
||||||
exports["SymbolDef"] = SymbolDef;
|
exports["SymbolDef"] = SymbolDef;
|
||||||
|
|
||||||
if (global.UGLIFY_DEBUG) {
|
|
||||||
exports["EXPECT_DIRECTIVE"] = EXPECT_DIRECTIVE;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -46,21 +46,21 @@ function read_source_map(code) {
|
|||||||
|
|
||||||
UglifyJS.minify = function(files, options) {
|
UglifyJS.minify = function(files, options) {
|
||||||
options = UglifyJS.defaults(options, {
|
options = UglifyJS.defaults(options, {
|
||||||
spidermonkey : false,
|
compress : {},
|
||||||
outSourceMap : null,
|
|
||||||
outFileName : null,
|
|
||||||
sourceRoot : null,
|
|
||||||
inSourceMap : null,
|
|
||||||
sourceMapUrl : null,
|
|
||||||
sourceMapInline : false,
|
|
||||||
fromString : false,
|
fromString : false,
|
||||||
warnings : false,
|
inSourceMap : null,
|
||||||
mangle : {},
|
mangle : {},
|
||||||
mangleProperties : false,
|
mangleProperties : false,
|
||||||
nameCache : null,
|
nameCache : null,
|
||||||
|
outFileName : null,
|
||||||
output : null,
|
output : null,
|
||||||
compress : {},
|
outSourceMap : null,
|
||||||
parse : {}
|
parse : {},
|
||||||
|
sourceMapInline : false,
|
||||||
|
sourceMapUrl : null,
|
||||||
|
sourceRoot : null,
|
||||||
|
spidermonkey : false,
|
||||||
|
warnings : false,
|
||||||
});
|
});
|
||||||
UglifyJS.base54.reset();
|
UglifyJS.base54.reset();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user