Merge bca9b4ea5b into 381bd3836e
This commit is contained in:
commit
52ffabc6ed
278
lib/compress.js
278
lib/compress.js
|
|
@ -121,8 +121,8 @@ merge(Compressor.prototype, {
|
||||||
node = node.process_expression(true);
|
node = node.process_expression(true);
|
||||||
}
|
}
|
||||||
var passes = +this.options.passes || 1;
|
var passes = +this.options.passes || 1;
|
||||||
for (var pass = 0; pass < passes && pass < 3; ++pass) {
|
for (var pass = 0; pass < passes; ++pass) {
|
||||||
if (pass > 0 || this.option("reduce_vars"))
|
if (this.option("reduce_vars"))
|
||||||
node.reset_opt_flags(this, true);
|
node.reset_opt_flags(this, true);
|
||||||
node = node.transform(this);
|
node = node.transform(this);
|
||||||
}
|
}
|
||||||
|
|
@ -145,7 +145,6 @@ merge(Compressor.prototype, {
|
||||||
this.warnings_produced = {};
|
this.warnings_produced = {};
|
||||||
},
|
},
|
||||||
before: function(node, descend, in_list) {
|
before: function(node, descend, in_list) {
|
||||||
if (node._squeezed) return node;
|
|
||||||
var was_scope = false;
|
var was_scope = false;
|
||||||
if (node instanceof AST_Scope) {
|
if (node instanceof AST_Scope) {
|
||||||
node = node.hoist_declarations(this);
|
node = node.hoist_declarations(this);
|
||||||
|
|
@ -157,7 +156,6 @@ merge(Compressor.prototype, {
|
||||||
node.drop_unused(this);
|
node.drop_unused(this);
|
||||||
descend(node, this);
|
descend(node, this);
|
||||||
}
|
}
|
||||||
node._squeezed = true;
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -167,12 +165,9 @@ merge(Compressor.prototype, {
|
||||||
function OPT(node, optimizer) {
|
function OPT(node, optimizer) {
|
||||||
node.DEFMETHOD("optimize", function(compressor){
|
node.DEFMETHOD("optimize", function(compressor){
|
||||||
var self = this;
|
var self = this;
|
||||||
if (self._optimized) return self;
|
|
||||||
if (compressor.has_directive("use asm")) return self;
|
if (compressor.has_directive("use asm")) return self;
|
||||||
var opt = optimizer(self, compressor);
|
var opt = optimizer(self, compressor);
|
||||||
opt._optimized = true;
|
return opt;
|
||||||
if (opt === self) return opt;
|
|
||||||
return opt.transform(compressor);
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -235,10 +230,6 @@ merge(Compressor.prototype, {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var tw = new TreeWalker(function(node, descend){
|
var tw = new TreeWalker(function(node, descend){
|
||||||
if (!(node instanceof AST_Directive || node instanceof AST_Constant)) {
|
|
||||||
node._squeezed = false;
|
|
||||||
node._optimized = false;
|
|
||||||
}
|
|
||||||
if (reduce_vars) {
|
if (reduce_vars) {
|
||||||
if (node instanceof AST_Toplevel) node.globals.each(reset_def);
|
if (node instanceof AST_Toplevel) node.globals.each(reset_def);
|
||||||
if (node instanceof AST_Scope) node.variables.each(reset_def);
|
if (node instanceof AST_Scope) node.variables.each(reset_def);
|
||||||
|
|
@ -384,7 +375,7 @@ merge(Compressor.prototype, {
|
||||||
return new ctor(props);
|
return new ctor(props);
|
||||||
};
|
};
|
||||||
|
|
||||||
function make_node_from_constant(compressor, val, orig) {
|
function make_node_from_constant(val, orig) {
|
||||||
switch (typeof val) {
|
switch (typeof val) {
|
||||||
case "string":
|
case "string":
|
||||||
return make_node(AST_String, orig, {
|
return make_node(AST_String, orig, {
|
||||||
|
|
@ -404,9 +395,9 @@ merge(Compressor.prototype, {
|
||||||
|
|
||||||
return make_node(AST_Number, orig, { value: val });
|
return make_node(AST_Number, orig, { value: val });
|
||||||
case "boolean":
|
case "boolean":
|
||||||
return make_node(val ? AST_True : AST_False, orig).optimize(compressor);
|
return make_node(val ? AST_True : AST_False, orig);
|
||||||
case "undefined":
|
case "undefined":
|
||||||
return make_node(AST_Undefined, orig).transform(compressor);
|
return make_node(AST_Undefined, orig);
|
||||||
default:
|
default:
|
||||||
if (val === null) {
|
if (val === null) {
|
||||||
return make_node(AST_Null, orig, { value: null });
|
return make_node(AST_Null, orig, { value: null });
|
||||||
|
|
@ -424,15 +415,17 @@ merge(Compressor.prototype, {
|
||||||
// func(something) because that changes the meaning of
|
// func(something) because that changes the meaning of
|
||||||
// the func (becomes lexical instead of global).
|
// the func (becomes lexical instead of global).
|
||||||
function maintain_this_binding(parent, orig, val) {
|
function maintain_this_binding(parent, orig, val) {
|
||||||
if (parent instanceof AST_Call && parent.expression === orig) {
|
if (parent instanceof AST_Call && parent.expression === orig
|
||||||
if (val instanceof AST_PropAccess || val instanceof AST_SymbolRef && val.name === "eval") {
|
&& (val instanceof AST_PropAccess
|
||||||
return make_node(AST_Seq, orig, {
|
|| val instanceof AST_SymbolRef && val.name === "eval")) {
|
||||||
car: make_node(AST_Number, orig, {
|
return orig instanceof AST_Seq
|
||||||
value: 0
|
&& orig.car instanceof AST_Number
|
||||||
}),
|
&& orig.car.value == 0 ? orig : make_node(AST_Seq, orig, {
|
||||||
cdr: val
|
car: make_node(AST_Number, orig, {
|
||||||
});
|
value: 0
|
||||||
}
|
}),
|
||||||
|
cdr: val
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
@ -649,8 +642,6 @@ merge(Compressor.prototype, {
|
||||||
statements[prev_stat_index] = make_node(AST_EmptyStatement, self);
|
statements[prev_stat_index] = make_node(AST_EmptyStatement, self);
|
||||||
var_defs_removed = true;
|
var_defs_removed = true;
|
||||||
}
|
}
|
||||||
// Further optimize statement after substitution.
|
|
||||||
stat.reset_opt_flags(compressor);
|
|
||||||
|
|
||||||
compressor.warn("Collapsing " + (is_constant ? "constant" : "variable") +
|
compressor.warn("Collapsing " + (is_constant ? "constant" : "variable") +
|
||||||
" " + var_name + " [{file}:{line},{col}]", node.start);
|
" " + var_name + " [{file}:{line},{col}]", node.start);
|
||||||
|
|
@ -817,7 +808,7 @@ merge(Compressor.prototype, {
|
||||||
body: body
|
body: body
|
||||||
});
|
});
|
||||||
stat.alternative = null;
|
stat.alternative = null;
|
||||||
ret = funs.concat([ stat.transform(compressor) ]);
|
ret = funs.concat([ stat ]);
|
||||||
continue loop;
|
continue loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -834,7 +825,7 @@ merge(Compressor.prototype, {
|
||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
ret.push(make_node(AST_Return, ret[0], {
|
ret.push(make_node(AST_Return, ret[0], {
|
||||||
value: null
|
value: null
|
||||||
}).transform(compressor));
|
}));
|
||||||
ret.unshift(stat);
|
ret.unshift(stat);
|
||||||
continue loop;
|
continue loop;
|
||||||
}
|
}
|
||||||
|
|
@ -858,7 +849,7 @@ merge(Compressor.prototype, {
|
||||||
stat.alternative = make_node(AST_BlockStatement, stat, {
|
stat.alternative = make_node(AST_BlockStatement, stat, {
|
||||||
body: body
|
body: body
|
||||||
});
|
});
|
||||||
ret = [ stat.transform(compressor) ];
|
ret = [ stat ];
|
||||||
continue loop;
|
continue loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -878,7 +869,7 @@ merge(Compressor.prototype, {
|
||||||
stat.alternative = make_node(AST_BlockStatement, stat.alternative, {
|
stat.alternative = make_node(AST_BlockStatement, stat.alternative, {
|
||||||
body: as_statement_array(stat.alternative).slice(0, -1)
|
body: as_statement_array(stat.alternative).slice(0, -1)
|
||||||
});
|
});
|
||||||
ret = [ stat.transform(compressor) ];
|
ret = [ stat ];
|
||||||
continue loop;
|
continue loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -982,7 +973,7 @@ merge(Compressor.prototype, {
|
||||||
} else {
|
} else {
|
||||||
left = AST_Seq.cons(left, right);
|
left = AST_Seq.cons(left, right);
|
||||||
}
|
}
|
||||||
return left.transform(compressor);
|
return left;
|
||||||
};
|
};
|
||||||
var ret = [], prev = null;
|
var ret = [], prev = null;
|
||||||
statements.forEach(function(stat){
|
statements.forEach(function(stat){
|
||||||
|
|
@ -1217,7 +1208,7 @@ merge(Compressor.prototype, {
|
||||||
properties: props
|
properties: props
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return make_node_from_constant(compressor, value, orig);
|
return make_node_from_constant(value, orig);
|
||||||
}
|
}
|
||||||
def(AST_Node, noop);
|
def(AST_Node, noop);
|
||||||
def(AST_Dot, function(compressor, suffix){
|
def(AST_Dot, function(compressor, suffix){
|
||||||
|
|
@ -1243,20 +1234,32 @@ merge(Compressor.prototype, {
|
||||||
node.DEFMETHOD("_find_defs", func);
|
node.DEFMETHOD("_find_defs", func);
|
||||||
});
|
});
|
||||||
|
|
||||||
function best_of(ast1, ast2) {
|
function best_of_expression(ast1, ast2) {
|
||||||
return ast1.print_to_string().length >
|
return ast1.print_to_string().length >
|
||||||
ast2.print_to_string().length
|
ast2.print_to_string().length
|
||||||
? ast2 : ast1;
|
? ast2 : ast1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function best_of_statement(ast1, ast2) {
|
function best_of_statement(ast1, ast2) {
|
||||||
return best_of(make_node(AST_SimpleStatement, ast1, {
|
return best_of_expression(make_node(AST_SimpleStatement, ast1, {
|
||||||
body: ast1
|
body: ast1
|
||||||
}), make_node(AST_SimpleStatement, ast2, {
|
}), make_node(AST_SimpleStatement, ast2, {
|
||||||
body: ast2
|
body: ast2
|
||||||
})).body;
|
})).body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function best_of(compressor, ast1, ast2) {
|
||||||
|
return (first_in_statement(compressor) ? best_of_statement : best_of_expression)(ast1, ast2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function best_of_constant(compressor, ev, ast) {
|
||||||
|
var self = compressor.self();
|
||||||
|
compressor.pop();
|
||||||
|
ev = ev.transform(compressor);
|
||||||
|
compressor.push(self);
|
||||||
|
return best_of(compressor, ev, ast);
|
||||||
|
}
|
||||||
|
|
||||||
// methods to evaluate a constant expression
|
// methods to evaluate a constant expression
|
||||||
(function (def){
|
(function (def){
|
||||||
// The evaluate method returns an array with one or two
|
// The evaluate method returns an array with one or two
|
||||||
|
|
@ -1277,11 +1280,18 @@ merge(Compressor.prototype, {
|
||||||
}
|
}
|
||||||
var node;
|
var node;
|
||||||
try {
|
try {
|
||||||
node = make_node_from_constant(compressor, val, this);
|
node = make_node_from_constant(val, this);
|
||||||
} catch(ex) {
|
} catch(ex) {
|
||||||
return [ this ];
|
return [ this ];
|
||||||
}
|
}
|
||||||
return [ best_of(node, this), val ];
|
return [ node, val ];
|
||||||
|
});
|
||||||
|
AST_Node.DEFMETHOD("evaluate_self", function(compressor){
|
||||||
|
var ev = this.evaluate(compressor);
|
||||||
|
if (ev.length > 1) {
|
||||||
|
return best_of_constant(compressor, ev[0], this);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
});
|
});
|
||||||
var unaryPrefix = makePredicate("! ~ - +");
|
var unaryPrefix = makePredicate("! ~ - +");
|
||||||
AST_Node.DEFMETHOD("is_constant", function(){
|
AST_Node.DEFMETHOD("is_constant", function(){
|
||||||
|
|
@ -1480,9 +1490,9 @@ merge(Compressor.prototype, {
|
||||||
var stat = make_node(AST_SimpleStatement, alt, {
|
var stat = make_node(AST_SimpleStatement, alt, {
|
||||||
body: alt
|
body: alt
|
||||||
});
|
});
|
||||||
return best_of(negated, stat) === stat ? alt : negated;
|
return best_of_expression(negated, stat) === stat ? alt : negated;
|
||||||
}
|
}
|
||||||
return best_of(negated, alt);
|
return best_of_expression(negated, alt);
|
||||||
}
|
}
|
||||||
def(AST_Node, function(){
|
def(AST_Node, function(){
|
||||||
return basic_negation(this);
|
return basic_negation(this);
|
||||||
|
|
@ -2109,9 +2119,12 @@ merge(Compressor.prototype, {
|
||||||
if (!this.has_pure_annotation(compressor) && compressor.pure_funcs(this)) {
|
if (!this.has_pure_annotation(compressor) && compressor.pure_funcs(this)) {
|
||||||
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 expression = this.expression.process_expression(false);
|
||||||
node.expression = node.expression.process_expression(false);
|
if (!this.expression.equivalent_to(expression)) {
|
||||||
return node;
|
var node = this.clone();
|
||||||
|
node.expression = expression;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
@ -2129,6 +2142,7 @@ merge(Compressor.prototype, {
|
||||||
switch (this.operator) {
|
switch (this.operator) {
|
||||||
case "&&":
|
case "&&":
|
||||||
case "||":
|
case "||":
|
||||||
|
if (right === this.right) return this;
|
||||||
var node = this.clone();
|
var node = this.clone();
|
||||||
node.right = right;
|
node.right = right;
|
||||||
return node;
|
return node;
|
||||||
|
|
@ -2242,7 +2256,9 @@ merge(Compressor.prototype, {
|
||||||
|
|
||||||
OPT(AST_DWLoop, function(self, compressor){
|
OPT(AST_DWLoop, function(self, compressor){
|
||||||
var cond = self.condition.evaluate(compressor);
|
var cond = self.condition.evaluate(compressor);
|
||||||
self.condition = cond[0];
|
if (cond.length > 1) {
|
||||||
|
self.condition = best_of_constant(compressor, cond[0], self.condition);
|
||||||
|
}
|
||||||
if (!compressor.option("loops")) return self;
|
if (!compressor.option("loops")) return self;
|
||||||
if (cond.length > 1) {
|
if (cond.length > 1) {
|
||||||
if (cond[1]) {
|
if (cond[1]) {
|
||||||
|
|
@ -2261,7 +2277,7 @@ merge(Compressor.prototype, {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (self instanceof AST_While) {
|
if (self instanceof AST_While) {
|
||||||
return make_node(AST_For, self, self).transform(compressor);
|
return make_node(AST_For, self, self);
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
});
|
});
|
||||||
|
|
@ -2272,11 +2288,10 @@ merge(Compressor.prototype, {
|
||||||
if (self.body instanceof AST_BlockStatement) {
|
if (self.body instanceof AST_BlockStatement) {
|
||||||
self.body = self.body.clone();
|
self.body = self.body.clone();
|
||||||
self.body.body = rest.concat(self.body.body.slice(1));
|
self.body.body = rest.concat(self.body.body.slice(1));
|
||||||
self.body = self.body.transform(compressor);
|
|
||||||
} else {
|
} else {
|
||||||
self.body = make_node(AST_BlockStatement, self.body, {
|
self.body = make_node(AST_BlockStatement, self.body, {
|
||||||
body: rest
|
body: rest
|
||||||
}).transform(compressor);
|
});
|
||||||
}
|
}
|
||||||
if_break_in_loop(self, compressor);
|
if_break_in_loop(self, compressor);
|
||||||
}
|
}
|
||||||
|
|
@ -2315,7 +2330,9 @@ merge(Compressor.prototype, {
|
||||||
var cond = self.condition;
|
var cond = self.condition;
|
||||||
if (cond) {
|
if (cond) {
|
||||||
cond = cond.evaluate(compressor);
|
cond = cond.evaluate(compressor);
|
||||||
self.condition = cond[0];
|
if (cond.length > 1) {
|
||||||
|
self.condition = best_of_constant(compressor, cond[0], self.condition);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!compressor.option("loops")) return self;
|
if (!compressor.option("loops")) return self;
|
||||||
if (cond) {
|
if (cond) {
|
||||||
|
|
@ -2348,7 +2365,6 @@ merge(Compressor.prototype, {
|
||||||
// “has no side effects”; also it doesn't work for cases like
|
// “has no side effects”; also it doesn't work for cases like
|
||||||
// `x && true`, though it probably should.
|
// `x && true`, though it probably should.
|
||||||
var cond = self.condition.evaluate(compressor);
|
var cond = self.condition.evaluate(compressor);
|
||||||
self.condition = cond[0];
|
|
||||||
if (cond.length > 1) {
|
if (cond.length > 1) {
|
||||||
if (cond[1]) {
|
if (cond[1]) {
|
||||||
compressor.warn("Condition always true [{file}:{line},{col}]", self.condition.start);
|
compressor.warn("Condition always true [{file}:{line},{col}]", self.condition.start);
|
||||||
|
|
@ -2358,7 +2374,7 @@ merge(Compressor.prototype, {
|
||||||
extract_declarations_from_unreachable_code(compressor, self.alternative, a);
|
extract_declarations_from_unreachable_code(compressor, self.alternative, a);
|
||||||
}
|
}
|
||||||
a.push(self.body);
|
a.push(self.body);
|
||||||
return make_node(AST_BlockStatement, self, { body: a }).transform(compressor);
|
return make_node(AST_BlockStatement, self, { body: a });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
compressor.warn("Condition always false [{file}:{line},{col}]", self.condition.start);
|
compressor.warn("Condition always false [{file}:{line},{col}]", self.condition.start);
|
||||||
|
|
@ -2366,9 +2382,10 @@ merge(Compressor.prototype, {
|
||||||
var a = [];
|
var a = [];
|
||||||
extract_declarations_from_unreachable_code(compressor, self.body, a);
|
extract_declarations_from_unreachable_code(compressor, self.body, a);
|
||||||
if (self.alternative) a.push(self.alternative);
|
if (self.alternative) a.push(self.alternative);
|
||||||
return make_node(AST_BlockStatement, self, { body: a }).transform(compressor);
|
return make_node(AST_BlockStatement, self, { body: a });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.condition = best_of_constant(compressor, cond[0], self.condition);
|
||||||
}
|
}
|
||||||
var negated = self.condition.negate(compressor);
|
var negated = self.condition.negate(compressor);
|
||||||
var self_condition_length = self.condition.print_to_string().length;
|
var self_condition_length = self.condition.print_to_string().length;
|
||||||
|
|
@ -2386,7 +2403,7 @@ merge(Compressor.prototype, {
|
||||||
if (is_empty(self.body) && is_empty(self.alternative)) {
|
if (is_empty(self.body) && is_empty(self.alternative)) {
|
||||||
return make_node(AST_SimpleStatement, self.condition, {
|
return make_node(AST_SimpleStatement, self.condition, {
|
||||||
body: self.condition
|
body: self.condition
|
||||||
}).transform(compressor);
|
});
|
||||||
}
|
}
|
||||||
if (self.body instanceof AST_SimpleStatement
|
if (self.body instanceof AST_SimpleStatement
|
||||||
&& self.alternative instanceof AST_SimpleStatement) {
|
&& self.alternative instanceof AST_SimpleStatement) {
|
||||||
|
|
@ -2396,7 +2413,7 @@ merge(Compressor.prototype, {
|
||||||
consequent : statement_to_expression(self.body),
|
consequent : statement_to_expression(self.body),
|
||||||
alternative : statement_to_expression(self.alternative)
|
alternative : statement_to_expression(self.alternative)
|
||||||
})
|
})
|
||||||
}).transform(compressor);
|
});
|
||||||
}
|
}
|
||||||
if (is_empty(self.alternative) && self.body instanceof AST_SimpleStatement) {
|
if (is_empty(self.alternative) && self.body instanceof AST_SimpleStatement) {
|
||||||
if (self_condition_length === negated_length && !negated_is_best
|
if (self_condition_length === negated_length && !negated_is_best
|
||||||
|
|
@ -2412,14 +2429,14 @@ merge(Compressor.prototype, {
|
||||||
left : negated,
|
left : negated,
|
||||||
right : statement_to_expression(self.body)
|
right : statement_to_expression(self.body)
|
||||||
})
|
})
|
||||||
}).transform(compressor);
|
});
|
||||||
return make_node(AST_SimpleStatement, self, {
|
return make_node(AST_SimpleStatement, self, {
|
||||||
body: make_node(AST_Binary, self, {
|
body: make_node(AST_Binary, self, {
|
||||||
operator : "&&",
|
operator : "&&",
|
||||||
left : self.condition,
|
left : self.condition,
|
||||||
right : statement_to_expression(self.body)
|
right : statement_to_expression(self.body)
|
||||||
})
|
})
|
||||||
}).transform(compressor);
|
});
|
||||||
}
|
}
|
||||||
if (self.body instanceof AST_EmptyStatement
|
if (self.body instanceof AST_EmptyStatement
|
||||||
&& self.alternative
|
&& self.alternative
|
||||||
|
|
@ -2430,7 +2447,7 @@ merge(Compressor.prototype, {
|
||||||
left : self.condition,
|
left : self.condition,
|
||||||
right : statement_to_expression(self.alternative)
|
right : statement_to_expression(self.alternative)
|
||||||
})
|
})
|
||||||
}).transform(compressor);
|
});
|
||||||
}
|
}
|
||||||
if (self.body instanceof AST_Exit
|
if (self.body instanceof AST_Exit
|
||||||
&& self.alternative instanceof AST_Exit
|
&& self.alternative instanceof AST_Exit
|
||||||
|
|
@ -2441,7 +2458,7 @@ merge(Compressor.prototype, {
|
||||||
consequent : self.body.value || make_node(AST_Undefined, self.body),
|
consequent : self.body.value || make_node(AST_Undefined, self.body),
|
||||||
alternative : self.alternative.value || make_node(AST_Undefined, self.alternative)
|
alternative : self.alternative.value || make_node(AST_Undefined, self.alternative)
|
||||||
})
|
})
|
||||||
}).transform(compressor);
|
});
|
||||||
}
|
}
|
||||||
if (self.body instanceof AST_If
|
if (self.body instanceof AST_If
|
||||||
&& !self.body.alternative
|
&& !self.body.alternative
|
||||||
|
|
@ -2450,7 +2467,7 @@ merge(Compressor.prototype, {
|
||||||
operator: "&&",
|
operator: "&&",
|
||||||
left: self.condition,
|
left: self.condition,
|
||||||
right: self.body.condition
|
right: self.body.condition
|
||||||
}).transform(compressor);
|
});
|
||||||
self.body = self.body.body;
|
self.body = self.body.body;
|
||||||
}
|
}
|
||||||
if (aborts(self.body)) {
|
if (aborts(self.body)) {
|
||||||
|
|
@ -2459,7 +2476,7 @@ merge(Compressor.prototype, {
|
||||||
self.alternative = null;
|
self.alternative = null;
|
||||||
return make_node(AST_BlockStatement, self, {
|
return make_node(AST_BlockStatement, self, {
|
||||||
body: [ self, alt ]
|
body: [ self, alt ]
|
||||||
}).transform(compressor);
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (aborts(self.alternative)) {
|
if (aborts(self.alternative)) {
|
||||||
|
|
@ -2469,7 +2486,7 @@ merge(Compressor.prototype, {
|
||||||
self.alternative = null;
|
self.alternative = null;
|
||||||
return make_node(AST_BlockStatement, self, {
|
return make_node(AST_BlockStatement, self, {
|
||||||
body: [ self, body ]
|
body: [ self, body ]
|
||||||
}).transform(compressor);
|
});
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
});
|
});
|
||||||
|
|
@ -2478,7 +2495,7 @@ merge(Compressor.prototype, {
|
||||||
if (self.body.length == 0 && compressor.option("conditionals")) {
|
if (self.body.length == 0 && compressor.option("conditionals")) {
|
||||||
return make_node(AST_SimpleStatement, self, {
|
return make_node(AST_SimpleStatement, self, {
|
||||||
body: self.expression
|
body: self.expression
|
||||||
}).transform(compressor);
|
});
|
||||||
}
|
}
|
||||||
for(;;) {
|
for(;;) {
|
||||||
var last_branch = self.body[self.body.length - 1];
|
var last_branch = self.body[self.body.length - 1];
|
||||||
|
|
@ -2496,7 +2513,7 @@ merge(Compressor.prototype, {
|
||||||
var exp = self.expression.evaluate(compressor);
|
var exp = self.expression.evaluate(compressor);
|
||||||
out: if (exp.length == 2) try {
|
out: if (exp.length == 2) try {
|
||||||
// constant expression
|
// constant expression
|
||||||
self.expression = exp[0];
|
self.expression = best_of_constant(compressor, exp[0], self.expression);
|
||||||
if (!compressor.option("dead_code")) break out;
|
if (!compressor.option("dead_code")) break out;
|
||||||
var value = exp[1];
|
var value = exp[1];
|
||||||
var in_if = false;
|
var in_if = false;
|
||||||
|
|
@ -2509,14 +2526,14 @@ merge(Compressor.prototype, {
|
||||||
// no need to descend these node types
|
// no need to descend these node types
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_Switch && node === self) {
|
else if (node === self) {
|
||||||
node = node.clone();
|
node = node.clone();
|
||||||
descend(node, this);
|
descend(node, this);
|
||||||
return ruined ? node : make_node(AST_BlockStatement, node, {
|
return ruined ? node : make_node(AST_BlockStatement, node, {
|
||||||
body: node.body.reduce(function(a, branch){
|
body: node.body.reduce(function(a, branch){
|
||||||
return a.concat(branch.body);
|
return a.concat(branch.body);
|
||||||
}, [])
|
}, [])
|
||||||
}).transform(compressor);
|
});
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_If || node instanceof AST_Try) {
|
else if (node instanceof AST_If || node instanceof AST_Try) {
|
||||||
var save = in_if;
|
var save = in_if;
|
||||||
|
|
@ -2656,7 +2673,7 @@ merge(Compressor.prototype, {
|
||||||
if (self.args.length != 1) {
|
if (self.args.length != 1) {
|
||||||
return make_node(AST_Array, self, {
|
return make_node(AST_Array, self, {
|
||||||
elements: self.args
|
elements: self.args
|
||||||
}).transform(compressor);
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "Object":
|
case "Object":
|
||||||
|
|
@ -2674,7 +2691,7 @@ merge(Compressor.prototype, {
|
||||||
left: self.args[0],
|
left: self.args[0],
|
||||||
operator: "+",
|
operator: "+",
|
||||||
right: make_node(AST_String, self, { value: "" })
|
right: make_node(AST_String, self, { value: "" })
|
||||||
}).transform(compressor);
|
});
|
||||||
break;
|
break;
|
||||||
case "Number":
|
case "Number":
|
||||||
if (self.args.length == 0) return make_node(AST_Number, self, {
|
if (self.args.length == 0) return make_node(AST_Number, self, {
|
||||||
|
|
@ -2683,7 +2700,7 @@ merge(Compressor.prototype, {
|
||||||
if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, {
|
if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, {
|
||||||
expression: self.args[0],
|
expression: self.args[0],
|
||||||
operator: "+"
|
operator: "+"
|
||||||
}).transform(compressor);
|
});
|
||||||
case "Boolean":
|
case "Boolean":
|
||||||
if (self.args.length == 0) return make_node(AST_False, self);
|
if (self.args.length == 0) return make_node(AST_False, self);
|
||||||
if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, {
|
if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, {
|
||||||
|
|
@ -2692,7 +2709,7 @@ merge(Compressor.prototype, {
|
||||||
operator: "!"
|
operator: "!"
|
||||||
}),
|
}),
|
||||||
operator: "!"
|
operator: "!"
|
||||||
}).transform(compressor);
|
});
|
||||||
break;
|
break;
|
||||||
case "Function":
|
case "Function":
|
||||||
// new Function() => function(){}
|
// new Function() => function(){}
|
||||||
|
|
@ -2757,7 +2774,7 @@ merge(Compressor.prototype, {
|
||||||
left: make_node(AST_String, self, { value: "" }),
|
left: make_node(AST_String, self, { value: "" }),
|
||||||
operator: "+",
|
operator: "+",
|
||||||
right: exp.expression
|
right: exp.expression
|
||||||
}).transform(compressor);
|
});
|
||||||
}
|
}
|
||||||
else if (exp instanceof AST_Dot && exp.expression instanceof AST_Array && exp.property == "join") EXIT: {
|
else if (exp instanceof AST_Dot && exp.expression instanceof AST_Array && exp.property == "join") EXIT: {
|
||||||
var separator;
|
var separator;
|
||||||
|
|
@ -2769,9 +2786,9 @@ merge(Compressor.prototype, {
|
||||||
var elements = [];
|
var elements = [];
|
||||||
var consts = [];
|
var consts = [];
|
||||||
exp.expression.elements.forEach(function(el) {
|
exp.expression.elements.forEach(function(el) {
|
||||||
el = el.evaluate(compressor);
|
var ev = el.evaluate(compressor);
|
||||||
if (el.length > 1) {
|
if (ev.length > 1) {
|
||||||
consts.push(el[1]);
|
consts.push(ev[1]);
|
||||||
} else {
|
} else {
|
||||||
if (consts.length > 0) {
|
if (consts.length > 0) {
|
||||||
elements.push(make_node(AST_String, self, {
|
elements.push(make_node(AST_String, self, {
|
||||||
|
|
@ -2779,7 +2796,7 @@ merge(Compressor.prototype, {
|
||||||
}));
|
}));
|
||||||
consts.length = 0;
|
consts.length = 0;
|
||||||
}
|
}
|
||||||
elements.push(el[0]);
|
elements.push(el);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (consts.length > 0) {
|
if (consts.length > 0) {
|
||||||
|
|
@ -2812,15 +2829,15 @@ merge(Compressor.prototype, {
|
||||||
left : prev,
|
left : prev,
|
||||||
right : el
|
right : el
|
||||||
});
|
});
|
||||||
}, first).transform(compressor);
|
}, first);
|
||||||
}
|
}
|
||||||
// need this awkward cloning to not affect original element
|
// need this awkward cloning to not affect original element
|
||||||
// best_of will decide which one to get through.
|
// best_of_expression will decide which one to get through.
|
||||||
var node = self.clone();
|
var node = self.clone();
|
||||||
node.expression = node.expression.clone();
|
node.expression = node.expression.clone();
|
||||||
node.expression.expression = node.expression.expression.clone();
|
node.expression.expression = node.expression.expression.clone();
|
||||||
node.expression.expression.elements = elements;
|
node.expression.expression.elements = elements;
|
||||||
return best_of(self, node);
|
return best_of_expression(self, node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (exp instanceof AST_Function) {
|
if (exp instanceof AST_Function) {
|
||||||
|
|
@ -2828,13 +2845,13 @@ merge(Compressor.prototype, {
|
||||||
var value = exp.body[0].value;
|
var value = exp.body[0].value;
|
||||||
if (!value || value.is_constant()) {
|
if (!value || value.is_constant()) {
|
||||||
var args = self.args.concat(value || make_node(AST_Undefined, self));
|
var args = self.args.concat(value || make_node(AST_Undefined, self));
|
||||||
return AST_Seq.from_array(args).transform(compressor);
|
return AST_Seq.from_array(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (compressor.option("side_effects")) {
|
if (compressor.option("side_effects")) {
|
||||||
if (!AST_Block.prototype.has_side_effects.call(exp, compressor)) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2847,7 +2864,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2869,7 +2886,7 @@ merge(Compressor.prototype, {
|
||||||
case "Function":
|
case "Function":
|
||||||
case "Error":
|
case "Error":
|
||||||
case "Array":
|
case "Array":
|
||||||
return make_node(AST_Call, self, self).transform(compressor);
|
return make_node(AST_Call, self, self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2879,8 +2896,12 @@ merge(Compressor.prototype, {
|
||||||
OPT(AST_Seq, function(self, compressor){
|
OPT(AST_Seq, function(self, compressor){
|
||||||
if (!compressor.option("side_effects"))
|
if (!compressor.option("side_effects"))
|
||||||
return self;
|
return self;
|
||||||
self.car = self.car.drop_side_effect_free(compressor, first_in_statement(compressor));
|
var car = self.car.drop_side_effect_free(compressor, first_in_statement(compressor));
|
||||||
if (!self.car) return maintain_this_binding(compressor.parent(), self, self.cdr);
|
if (car) {
|
||||||
|
self.car = car;
|
||||||
|
} else {
|
||||||
|
return maintain_this_binding(compressor.parent(), self, self.cdr);
|
||||||
|
}
|
||||||
if (compressor.option("cascade")) {
|
if (compressor.option("cascade")) {
|
||||||
var left;
|
var left;
|
||||||
if (self.car instanceof AST_Assign
|
if (self.car instanceof AST_Assign
|
||||||
|
|
@ -2932,7 +2953,7 @@ merge(Compressor.prototype, {
|
||||||
var x = seq.to_array();
|
var x = seq.to_array();
|
||||||
this.expression = x.pop();
|
this.expression = x.pop();
|
||||||
x.push(this);
|
x.push(this);
|
||||||
seq = AST_Seq.from_array(x).transform(compressor);
|
seq = AST_Seq.from_array(x);
|
||||||
return seq;
|
return seq;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2945,9 +2966,7 @@ merge(Compressor.prototype, {
|
||||||
|
|
||||||
OPT(AST_UnaryPrefix, function(self, compressor){
|
OPT(AST_UnaryPrefix, function(self, compressor){
|
||||||
var seq = self.lift_sequences(compressor);
|
var seq = self.lift_sequences(compressor);
|
||||||
if (seq !== self) {
|
if (seq !== self) return seq;
|
||||||
return seq;
|
|
||||||
}
|
|
||||||
var e = self.expression;
|
var e = self.expression;
|
||||||
if (compressor.option("side_effects") && self.operator == "void") {
|
if (compressor.option("side_effects") && self.operator == "void") {
|
||||||
e = e.drop_side_effect_free(compressor);
|
e = e.drop_side_effect_free(compressor);
|
||||||
|
|
@ -2955,7 +2974,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (compressor.option("booleans") && compressor.in_boolean_context()) {
|
if (compressor.option("booleans") && compressor.in_boolean_context()) {
|
||||||
|
|
@ -2966,8 +2985,7 @@ merge(Compressor.prototype, {
|
||||||
return e.expression;
|
return e.expression;
|
||||||
}
|
}
|
||||||
if (e instanceof AST_Binary) {
|
if (e instanceof AST_Binary) {
|
||||||
var statement = first_in_statement(compressor);
|
self = best_of(compressor, self, e.negate(compressor, first_in_statement(compressor)));
|
||||||
self = (statement ? best_of_statement : best_of)(self, e.negate(compressor, statement));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "typeof":
|
case "typeof":
|
||||||
|
|
@ -2977,10 +2995,19 @@ merge(Compressor.prototype, {
|
||||||
return make_node(AST_Seq, self, {
|
return make_node(AST_Seq, self, {
|
||||||
car: e,
|
car: e,
|
||||||
cdr: make_node(AST_True, self)
|
cdr: make_node(AST_True, self)
|
||||||
}).optimize(compressor);
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return self.evaluate(compressor)[0];
|
if (e instanceof AST_Infinity && self.operator == "-") {
|
||||||
|
self.expression = e.transform(compressor);
|
||||||
|
return self;
|
||||||
|
} else if (e instanceof AST_Number
|
||||||
|
&& (self.operator == "-"
|
||||||
|
|| self.operator == "!"
|
||||||
|
&& (e.value == 0 || e.value == 1))) {
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
return self.evaluate_self(compressor);
|
||||||
});
|
});
|
||||||
|
|
||||||
function has_side_effects_or_prop_access(node, compressor) {
|
function has_side_effects_or_prop_access(node, compressor) {
|
||||||
|
|
@ -2998,7 +3025,7 @@ merge(Compressor.prototype, {
|
||||||
var x = seq.to_array();
|
var x = seq.to_array();
|
||||||
this.left = x.pop();
|
this.left = x.pop();
|
||||||
x.push(this);
|
x.push(this);
|
||||||
seq = AST_Seq.from_array(x).transform(compressor);
|
seq = AST_Seq.from_array(x);
|
||||||
return seq;
|
return seq;
|
||||||
}
|
}
|
||||||
if (this.right instanceof AST_Seq
|
if (this.right instanceof AST_Seq
|
||||||
|
|
@ -3008,7 +3035,7 @@ merge(Compressor.prototype, {
|
||||||
var x = seq.to_array();
|
var x = seq.to_array();
|
||||||
this.right = x.pop();
|
this.right = x.pop();
|
||||||
x.push(this);
|
x.push(this);
|
||||||
seq = AST_Seq.from_array(x).transform(compressor);
|
seq = AST_Seq.from_array(x);
|
||||||
return seq;
|
return seq;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3071,7 +3098,8 @@ merge(Compressor.prototype, {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self = self.lift_sequences(compressor);
|
var seq = self.lift_sequences(compressor);
|
||||||
|
if (seq !== self) return seq;
|
||||||
if (compressor.option("comparisons")) switch (self.operator) {
|
if (compressor.option("comparisons")) switch (self.operator) {
|
||||||
case "===":
|
case "===":
|
||||||
case "!==":
|
case "!==":
|
||||||
|
|
@ -3092,7 +3120,7 @@ merge(Compressor.prototype, {
|
||||||
if (expr instanceof AST_SymbolRef ? !expr.undeclared()
|
if (expr instanceof AST_SymbolRef ? !expr.undeclared()
|
||||||
: !(expr instanceof AST_PropAccess) || compressor.option("screw_ie8")) {
|
: !(expr instanceof AST_PropAccess) || compressor.option("screw_ie8")) {
|
||||||
self.right = expr;
|
self.right = expr;
|
||||||
self.left = make_node(AST_Undefined, self.left).optimize(compressor);
|
self.left = make_node(AST_Undefined, self.left);
|
||||||
if (self.operator.length == 2) self.operator += "=";
|
if (self.operator.length == 2) self.operator += "=";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3107,13 +3135,13 @@ merge(Compressor.prototype, {
|
||||||
return make_node(AST_Seq, self, {
|
return make_node(AST_Seq, self, {
|
||||||
car: self.left,
|
car: self.left,
|
||||||
cdr: make_node(AST_False, self)
|
cdr: make_node(AST_False, self)
|
||||||
}).optimize(compressor);
|
});
|
||||||
}
|
}
|
||||||
if (ll.length > 1 && ll[1]) {
|
if (ll.length > 1 && ll[1]) {
|
||||||
return rr[0];
|
return best_of_constant(compressor, rr[0], self.right);
|
||||||
}
|
}
|
||||||
if (rr.length > 1 && rr[1]) {
|
if (rr.length > 1 && rr[1]) {
|
||||||
return ll[0];
|
return best_of_constant(compressor, ll[0], self.left);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "||":
|
case "||":
|
||||||
|
|
@ -3124,13 +3152,13 @@ merge(Compressor.prototype, {
|
||||||
return make_node(AST_Seq, self, {
|
return make_node(AST_Seq, self, {
|
||||||
car: self.left,
|
car: self.left,
|
||||||
cdr: make_node(AST_True, self)
|
cdr: make_node(AST_True, self)
|
||||||
}).optimize(compressor);
|
});
|
||||||
}
|
}
|
||||||
if (ll.length > 1 && !ll[1]) {
|
if (ll.length > 1 && !ll[1]) {
|
||||||
return rr[0];
|
return best_of_constant(compressor, rr[0], self.right);
|
||||||
}
|
}
|
||||||
if (rr.length > 1 && !rr[1]) {
|
if (rr.length > 1 && !rr[1]) {
|
||||||
return ll[0];
|
return best_of_constant(compressor, ll[0], self.left);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "+":
|
case "+":
|
||||||
|
|
@ -3141,26 +3169,25 @@ merge(Compressor.prototype, {
|
||||||
return make_node(AST_Seq, self, {
|
return make_node(AST_Seq, self, {
|
||||||
car: self.right,
|
car: self.right,
|
||||||
cdr: make_node(AST_True, self)
|
cdr: make_node(AST_True, self)
|
||||||
}).optimize(compressor);
|
});
|
||||||
}
|
}
|
||||||
if (rr.length > 1 && rr[0] instanceof AST_String && rr[1]) {
|
if (rr.length > 1 && rr[0] instanceof AST_String && rr[1]) {
|
||||||
compressor.warn("+ in boolean context always true [{file}:{line},{col}]", self.start);
|
compressor.warn("+ in boolean context always true [{file}:{line},{col}]", self.start);
|
||||||
return make_node(AST_Seq, self, {
|
return make_node(AST_Seq, self, {
|
||||||
car: self.left,
|
car: self.left,
|
||||||
cdr: make_node(AST_True, self)
|
cdr: make_node(AST_True, self)
|
||||||
}).optimize(compressor);
|
});
|
||||||
}
|
}
|
||||||
break;
|
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)
|
||||||
|| compressor.parent() instanceof AST_Assign) {
|
|| compressor.parent() instanceof AST_Assign) {
|
||||||
var statement = first_in_statement(compressor);
|
|
||||||
var negated = make_node(AST_UnaryPrefix, self, {
|
var negated = make_node(AST_UnaryPrefix, self, {
|
||||||
operator: "!",
|
operator: "!",
|
||||||
expression: self.negate(compressor, statement)
|
expression: self.negate(compressor, first_in_statement(compressor))
|
||||||
});
|
});
|
||||||
self = (statement ? best_of_statement : best_of)(self, negated);
|
self = best_of(compressor, self, negated);
|
||||||
}
|
}
|
||||||
if (compressor.option("unsafe_comps")) {
|
if (compressor.option("unsafe_comps")) {
|
||||||
switch (self.operator) {
|
switch (self.operator) {
|
||||||
|
|
@ -3186,7 +3213,7 @@ merge(Compressor.prototype, {
|
||||||
&& self.left.left.getValue() == ""
|
&& self.left.left.getValue() == ""
|
||||||
&& self.right.is_string(compressor)) {
|
&& self.right.is_string(compressor)) {
|
||||||
self.left = self.left.right;
|
self.left = self.left.right;
|
||||||
return self.transform(compressor);
|
return self;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (compressor.option("evaluate")) {
|
if (compressor.option("evaluate")) {
|
||||||
|
|
@ -3312,9 +3339,9 @@ merge(Compressor.prototype, {
|
||||||
});
|
});
|
||||||
if (self.right instanceof AST_Constant
|
if (self.right instanceof AST_Constant
|
||||||
&& !(self.left instanceof AST_Constant)) {
|
&& !(self.left instanceof AST_Constant)) {
|
||||||
self = best_of(reversed, self);
|
self = best_of(compressor, reversed, self);
|
||||||
} else {
|
} else {
|
||||||
self = best_of(self, reversed);
|
self = best_of(compressor, self, reversed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (associative && self.is_number(compressor)) {
|
if (associative && self.is_number(compressor)) {
|
||||||
|
|
@ -3409,9 +3436,8 @@ merge(Compressor.prototype, {
|
||||||
right : self.right.left
|
right : self.right.left
|
||||||
});
|
});
|
||||||
self.right = self.right.right;
|
self.right = self.right.right;
|
||||||
return self.transform(compressor);
|
|
||||||
}
|
}
|
||||||
return self.evaluate(compressor)[0];
|
return self.evaluate_self(compressor);
|
||||||
});
|
});
|
||||||
|
|
||||||
OPT(AST_SymbolRef, function(self, compressor){
|
OPT(AST_SymbolRef, function(self, compressor){
|
||||||
|
|
@ -3426,11 +3452,11 @@ merge(Compressor.prototype, {
|
||||||
&& (!self.scope.uses_with || !compressor.find_parent(AST_With))) {
|
&& (!self.scope.uses_with || !compressor.find_parent(AST_With))) {
|
||||||
switch (self.name) {
|
switch (self.name) {
|
||||||
case "undefined":
|
case "undefined":
|
||||||
return make_node(AST_Undefined, self).transform(compressor);
|
return make_node(AST_Undefined, self);
|
||||||
case "NaN":
|
case "NaN":
|
||||||
return make_node(AST_NaN, self).transform(compressor);
|
return make_node(AST_NaN, self);
|
||||||
case "Infinity":
|
case "Infinity":
|
||||||
return make_node(AST_Infinity, self).transform(compressor);
|
return make_node(AST_Infinity, self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (compressor.option("evaluate") && compressor.option("reduce_vars")) {
|
if (compressor.option("evaluate") && compressor.option("reduce_vars")) {
|
||||||
|
|
@ -3439,11 +3465,12 @@ merge(Compressor.prototype, {
|
||||||
if (d.should_replace === undefined) {
|
if (d.should_replace === undefined) {
|
||||||
var init = d.fixed.evaluate(compressor);
|
var init = d.fixed.evaluate(compressor);
|
||||||
if (init.length > 1) {
|
if (init.length > 1) {
|
||||||
var value = init[0].print_to_string().length;
|
init = best_of_constant(compressor, init[0], d.fixed);
|
||||||
|
var value = init.print_to_string().length;
|
||||||
var name = d.name.length;
|
var name = d.name.length;
|
||||||
var freq = d.references.length;
|
var freq = d.references.length;
|
||||||
var overhead = d.global || !freq ? 0 : (name + 2 + value) / freq;
|
var overhead = d.global || !freq ? 0 : (name + 2 + value) / freq;
|
||||||
d.should_replace = value <= name + overhead ? init[0] : false;
|
d.should_replace = value <= name + overhead ? init : false;
|
||||||
} else {
|
} else {
|
||||||
d.should_replace = false;
|
d.should_replace = false;
|
||||||
}
|
}
|
||||||
|
|
@ -3484,7 +3511,8 @@ merge(Compressor.prototype, {
|
||||||
var ASSIGN_OPS = [ '+', '-', '/', '*', '%', '>>', '<<', '>>>', '|', '^', '&' ];
|
var ASSIGN_OPS = [ '+', '-', '/', '*', '%', '>>', '<<', '>>>', '|', '^', '&' ];
|
||||||
var ASSIGN_OPS_COMMUTATIVE = [ '*', '|', '^', '&' ];
|
var ASSIGN_OPS_COMMUTATIVE = [ '*', '|', '^', '&' ];
|
||||||
OPT(AST_Assign, function(self, compressor){
|
OPT(AST_Assign, function(self, compressor){
|
||||||
self = self.lift_sequences(compressor);
|
var seq = self.lift_sequences(compressor);
|
||||||
|
if (seq !== self) return seq;
|
||||||
if (self.operator == "=" && self.left instanceof AST_SymbolRef && self.right instanceof AST_Binary) {
|
if (self.operator == "=" && self.left instanceof AST_SymbolRef && self.right instanceof AST_Binary) {
|
||||||
// x = expr1 OP expr2
|
// x = expr1 OP expr2
|
||||||
if (self.right.left instanceof AST_SymbolRef
|
if (self.right.left instanceof AST_SymbolRef
|
||||||
|
|
@ -3523,9 +3551,8 @@ merge(Compressor.prototype, {
|
||||||
return maintain_this_binding(compressor.parent(), self, self.alternative);
|
return maintain_this_binding(compressor.parent(), self, self.alternative);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var statement = first_in_statement(compressor);
|
var negated = self.condition.negate(compressor, first_in_statement(compressor));
|
||||||
var negated = cond[0].negate(compressor, statement);
|
if (best_of(compressor, self.condition, negated) === negated) {
|
||||||
if ((statement ? best_of_statement : best_of)(cond[0], negated) === negated) {
|
|
||||||
self = make_node(AST_Conditional, self, {
|
self = make_node(AST_Conditional, self, {
|
||||||
condition: negated,
|
condition: negated,
|
||||||
consequent: self.alternative,
|
consequent: self.alternative,
|
||||||
|
|
@ -3589,7 +3616,7 @@ merge(Compressor.prototype, {
|
||||||
return make_node(AST_Seq, self, {
|
return make_node(AST_Seq, self, {
|
||||||
car: self.condition,
|
car: self.condition,
|
||||||
cdr: consequent
|
cdr: consequent
|
||||||
}).optimize(compressor);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_true(self.consequent)) {
|
if (is_true(self.consequent)) {
|
||||||
|
|
@ -3696,7 +3723,7 @@ merge(Compressor.prototype, {
|
||||||
return make_node(AST_Dot, self, {
|
return make_node(AST_Dot, self, {
|
||||||
expression : self.expression,
|
expression : self.expression,
|
||||||
property : prop
|
property : prop
|
||||||
}).optimize(compressor);
|
});
|
||||||
}
|
}
|
||||||
var v = parseFloat(prop);
|
var v = parseFloat(prop);
|
||||||
if (!isNaN(v) && v.toString() == prop) {
|
if (!isNaN(v) && v.toString() == prop) {
|
||||||
|
|
@ -3705,7 +3732,7 @@ merge(Compressor.prototype, {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return self.evaluate(compressor)[0];
|
return self.evaluate_self(compressor);
|
||||||
});
|
});
|
||||||
|
|
||||||
OPT(AST_Dot, function(self, compressor){
|
OPT(AST_Dot, function(self, compressor){
|
||||||
|
|
@ -3720,7 +3747,7 @@ merge(Compressor.prototype, {
|
||||||
property : make_node(AST_String, self, {
|
property : make_node(AST_String, self, {
|
||||||
value: prop
|
value: prop
|
||||||
})
|
})
|
||||||
}).optimize(compressor);
|
});
|
||||||
}
|
}
|
||||||
if (compressor.option("unsafe_proto")
|
if (compressor.option("unsafe_proto")
|
||||||
&& self.expression instanceof AST_Dot
|
&& self.expression instanceof AST_Dot
|
||||||
|
|
@ -3744,16 +3771,15 @@ merge(Compressor.prototype, {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return self.evaluate(compressor)[0];
|
return self.evaluate_self(compressor);
|
||||||
});
|
});
|
||||||
|
|
||||||
function literals_in_boolean_context(self, compressor) {
|
function literals_in_boolean_context(self, compressor) {
|
||||||
if (compressor.option("booleans") && compressor.in_boolean_context()) {
|
if (compressor.option("booleans") && compressor.in_boolean_context()) {
|
||||||
var best = first_in_statement(compressor) ? best_of_statement : best_of;
|
return best_of_constant(compressor, make_node(AST_Seq, self, {
|
||||||
return best(self, make_node(AST_Seq, self, {
|
|
||||||
car: self,
|
car: self,
|
||||||
cdr: make_node(AST_True, self)
|
cdr: make_node(AST_True, self)
|
||||||
}).optimize(compressor));
|
}), self);
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -270,19 +270,14 @@ collapse_vars_if: {
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f1() {
|
function f1() {
|
||||||
sideeffect();
|
return sideeffect(), "x" != "Bar" + (g1 + g2) / 4 ? g9 : g5;
|
||||||
return "x" != "Bar" + (g1 + g2) / 4 ? g9 : g5;
|
|
||||||
}
|
}
|
||||||
function f2() {
|
function f2() {
|
||||||
var x = g1 + g2;
|
var x = g1 + g2;
|
||||||
sideeffect();
|
return sideeffect(), "x" != "Bar" + x / 4 ? g9 : g5;
|
||||||
return "x" != "Bar" + x / 4 ? g9 : g5;
|
|
||||||
}
|
}
|
||||||
function f3(x) {
|
function f3(x) {
|
||||||
if (x) {
|
return x ? 1 : 2;
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -551,13 +546,11 @@ collapse_vars_switch: {
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f1() {
|
function f1() {
|
||||||
sideeffect();
|
switch (sideeffect(), "Bar" + (g1 + g2) / 4) { case 0: return g9 }
|
||||||
switch ("Bar" + (g1 + g2) / 4) { case 0: return g9 }
|
|
||||||
}
|
}
|
||||||
function f2() {
|
function f2() {
|
||||||
var x = g1 + g2;
|
var x = g1 + g2;
|
||||||
sideeffect();
|
switch (sideeffect(), "Bar" + x / 4) { case 0: return g9 }
|
||||||
switch ("Bar" + x / 4) { case 0: return g9 }
|
|
||||||
}
|
}
|
||||||
function f3(x) {
|
function f3(x) {
|
||||||
// verify no extraneous semicolon in case block before return
|
// verify no extraneous semicolon in case block before return
|
||||||
|
|
@ -698,10 +691,10 @@ collapse_vars_lvalues_drop_assign: {
|
||||||
function f3(x) { var a = (x -= 3); return x + a; }
|
function f3(x) { var a = (x -= 3); return x + a; }
|
||||||
function f4(x) { var a = (x -= 3); return x + a; }
|
function f4(x) { var a = (x -= 3); return x + a; }
|
||||||
function f5(x) { var v = (e1(), e2()), c = v = --x; return x - c; }
|
function f5(x) { var v = (e1(), e2()), c = v = --x; return x - c; }
|
||||||
function f6(x) { e1(), e2(); return --x - x; }
|
function f6(x) { return e1(), e2(), --x - x; }
|
||||||
function f7(x) { var v = (e1(), e2()), c = v - x; return x - c; }
|
function f7(x) { return x - (e1(), e2() - x); }
|
||||||
function f8(x) { var v = (e1(), e2()); return x - (v - x); }
|
function f8(x) { return x - (e1(), e2() - x); }
|
||||||
function f9(x) { e1(); return e2() - x - x; }
|
function f9(x) { return e1(), e2() - x - x; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1142,8 +1135,7 @@ collapse_vars_constants: {
|
||||||
}
|
}
|
||||||
function f3(x) {
|
function f3(x) {
|
||||||
var b = x.prop;
|
var b = x.prop;
|
||||||
sideeffect1();
|
return sideeffect1(), b + -9;
|
||||||
return b + -9;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1193,10 +1185,10 @@ collapse_vars_short_circuit: {
|
||||||
function f14(x,y) { var a = foo(), b = bar(); return (b - a) || (x - y); }
|
function f14(x,y) { var a = foo(), b = bar(); return (b - a) || (x - y); }
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f0(x) { foo(); return bar() || x; }
|
function f0(x) { return foo(), bar() || x; }
|
||||||
function f1(x) { foo(); return bar() && x; }
|
function f1(x) { return foo(), bar() && x; }
|
||||||
function f2(x) { var a = foo(), b = bar(); return x && a && b; }
|
function f2(x) { var a = foo(), b = bar(); return x && a && b; }
|
||||||
function f3(x) { var a = foo(); bar(); return a && x; }
|
function f3(x) { var a = foo(); return bar(), a && x; }
|
||||||
function f4(x) { var a = foo(), b = bar(); return a && x && b; }
|
function f4(x) { var a = foo(), b = bar(); return a && x && b; }
|
||||||
function f5(x) { var a = foo(), b = bar(); return x || a || b; }
|
function f5(x) { var a = foo(), b = bar(); return x || a || b; }
|
||||||
function f6(x) { var a = foo(), b = bar(); return a || x || b; }
|
function f6(x) { var a = foo(), b = bar(); return a || x || b; }
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ ifs_3_should_warn: {
|
||||||
evaluate : true,
|
evaluate : true,
|
||||||
booleans : true,
|
booleans : true,
|
||||||
side_effects : true,
|
side_effects : true,
|
||||||
|
passes : 3,
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
var x, y;
|
var x, y;
|
||||||
|
|
@ -98,6 +99,7 @@ ifs_5: {
|
||||||
if_return: true,
|
if_return: true,
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
comparisons: true,
|
comparisons: true,
|
||||||
|
passes: 2,
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
function f() {
|
function f() {
|
||||||
|
|
@ -187,7 +189,8 @@ cond_1: {
|
||||||
|
|
||||||
cond_2: {
|
cond_2: {
|
||||||
options = {
|
options = {
|
||||||
conditionals: true
|
conditionals: true,
|
||||||
|
passes: 2,
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
var x, FooBar;
|
var x, FooBar;
|
||||||
|
|
@ -276,6 +279,7 @@ cond_7: {
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
evaluate : true,
|
evaluate : true,
|
||||||
|
passes : 3,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -338,7 +342,8 @@ cond_7: {
|
||||||
cond_7_1: {
|
cond_7_1: {
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
evaluate : true
|
evaluate : true,
|
||||||
|
passes : 2,
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
var x;
|
var x;
|
||||||
|
|
@ -359,7 +364,8 @@ cond_8: {
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
evaluate : true,
|
evaluate : true,
|
||||||
booleans : false
|
booleans : false,
|
||||||
|
passes : 2,
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
var a;
|
var a;
|
||||||
|
|
@ -443,7 +449,8 @@ cond_8b: {
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
evaluate : true,
|
evaluate : true,
|
||||||
booleans : true
|
booleans : true,
|
||||||
|
passes : 2,
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
var a;
|
var a;
|
||||||
|
|
@ -526,7 +533,8 @@ cond_8c: {
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
evaluate : false,
|
evaluate : false,
|
||||||
booleans : false
|
booleans : false,
|
||||||
|
passes : 2,
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
var a;
|
var a;
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ dead_code_constant_boolean_should_warn_more: {
|
||||||
conditionals : true,
|
conditionals : true,
|
||||||
evaluate : true,
|
evaluate : true,
|
||||||
side_effects : true,
|
side_effects : true,
|
||||||
|
passes : 2,
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
while (!((foo && bar) || (x + "0"))) {
|
while (!((foo && bar) || (x + "0"))) {
|
||||||
|
|
|
||||||
|
|
@ -696,7 +696,7 @@ in_boolean_context: {
|
||||||
!b("foo"),
|
!b("foo"),
|
||||||
!b([1, 2]),
|
!b([1, 2]),
|
||||||
!b(/foo/),
|
!b(/foo/),
|
||||||
![1, foo()],
|
(foo(), !1),
|
||||||
(foo(), !1)
|
(foo(), !1)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ mixed: {
|
||||||
}
|
}
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:126,22]',
|
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:126,22]',
|
||||||
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:127,22]',
|
|
||||||
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:129,8]',
|
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:129,8]',
|
||||||
|
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:127,22]',
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -152,25 +152,25 @@ should_warn: {
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:128,23]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:128,23]",
|
||||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:128,23]",
|
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:128,23]",
|
||||||
"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: Condition always true [test/compress/issue-1261.js:129,23]",
|
|
||||||
"WARN: Boolean || always true [test/compress/issue-1261.js:130,8]",
|
"WARN: Boolean || 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: Condition always false [test/compress/issue-1261.js:131,23]",
|
|
||||||
"WARN: Boolean && always false [test/compress/issue-1261.js:132,8]",
|
"WARN: Boolean && 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: Condition always true [test/compress/issue-1261.js:133,23]",
|
|
||||||
"WARN: + in boolean context always true [test/compress/issue-1261.js:134,8]",
|
"WARN: + in boolean context always true [test/compress/issue-1261.js:134,8]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:134,31]",
|
|
||||||
"WARN: Condition always true [test/compress/issue-1261.js:134,8]",
|
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:135,23]",
|
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:136,24]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:136,24]",
|
||||||
"WARN: Condition always true [test/compress/issue-1261.js:136,8]",
|
"WARN: Condition always true [test/compress/issue-1261.js:136,8]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:137,31]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:137,31]",
|
||||||
"WARN: Condition always false [test/compress/issue-1261.js:137,8]",
|
"WARN: Condition always false [test/compress/issue-1261.js:137,8]",
|
||||||
|
"WARN: Condition always true [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:130,8]",
|
||||||
|
"WARN: Condition always false [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:132,8]",
|
||||||
|
"WARN: Condition always true [test/compress/issue-1261.js:133,23]",
|
||||||
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:133,23]",
|
||||||
|
"WARN: Condition always true [test/compress/issue-1261.js:134,8]",
|
||||||
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:134,31]",
|
||||||
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:135,23]",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
inner_reference: {
|
inner_reference: {
|
||||||
options = {
|
options = {
|
||||||
|
passes: 2,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -14,6 +15,5 @@ inner_reference: {
|
||||||
!function f(a) {
|
!function f(a) {
|
||||||
return a && f(a - 1) + a;
|
return a && f(a - 1) + a;
|
||||||
}(42);
|
}(42);
|
||||||
!void 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@ wrongly_optimized: {
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
booleans: true,
|
booleans: true,
|
||||||
evaluate: true
|
evaluate: true,
|
||||||
|
sequences: true,
|
||||||
|
passes: 2,
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
function func() {
|
function func() {
|
||||||
|
|
@ -16,7 +18,6 @@ wrongly_optimized: {
|
||||||
function func() {
|
function func() {
|
||||||
foo();
|
foo();
|
||||||
}
|
}
|
||||||
// TODO: optimize to `func(), bar()`
|
func(), bar();
|
||||||
(func(), 0) || bar();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -381,6 +381,7 @@ issue_1288_side_effects: {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
negate_iife: true,
|
negate_iife: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
|
passes: 2,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
if (w) ;
|
if (w) ;
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ comparisons: {
|
||||||
evaluate_1: {
|
evaluate_1: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
passes: 2,
|
||||||
unsafe_math: false,
|
unsafe_math: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -78,6 +79,7 @@ evaluate_1: {
|
||||||
evaluate_2: {
|
evaluate_2: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
passes: 2,
|
||||||
unsafe_math: true,
|
unsafe_math: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -98,7 +100,7 @@ evaluate_2: {
|
||||||
console.log(
|
console.log(
|
||||||
x + 1 + 2,
|
x + 1 + 2,
|
||||||
2 * x,
|
2 * x,
|
||||||
3 + +x,
|
+x + 3,
|
||||||
1 + x + 2 + 3,
|
1 + x + 2 + 3,
|
||||||
3 | x,
|
3 | x,
|
||||||
6 + x--,
|
6 + x--,
|
||||||
|
|
@ -120,7 +122,7 @@ evaluate_3: {
|
||||||
console.log(1 + Number(x) + 2);
|
console.log(1 + Number(x) + 2);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(3 + +x);
|
console.log(+x + 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,9 +53,7 @@ reduce_vars: {
|
||||||
console.log(-3);
|
console.log(-3);
|
||||||
eval("console.log(a);");
|
eval("console.log(a);");
|
||||||
})(eval);
|
})(eval);
|
||||||
(function() {
|
"yes";
|
||||||
return "yes";
|
|
||||||
})();
|
|
||||||
console.log(2);
|
console.log(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
129
test/compress/transform-optimize.js
Normal file
129
test/compress/transform-optimize.js
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
booleans_evaluate: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(typeof void 0 != "undefined");
|
||||||
|
console.log(1 == 1, 1 === 1)
|
||||||
|
console.log(1 != 1, 1 !== 1)
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(!1);
|
||||||
|
console.log(!0, !0);
|
||||||
|
console.log(!1, !1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
booleans_global_defs: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
evaluate: true,
|
||||||
|
global_defs: {
|
||||||
|
A: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(A == 1);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(!0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
condition_evaluate: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
dead_code: false,
|
||||||
|
evaluate: true,
|
||||||
|
loops: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
while (1 === 2);
|
||||||
|
for (; 1 == true;);
|
||||||
|
if (void 0 == null);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
while (!1);
|
||||||
|
for (; !0;);
|
||||||
|
if (!0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if_else_empty_1: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
if ({} ? a : b); else {}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!{} ? b : a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if_else_empty_2: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
passes: 2,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
if ({} ? a : b); else {}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!{} ? b : a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
label_if_break_1: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
L: if (true) {
|
||||||
|
a;
|
||||||
|
break L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
label_if_break_2: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
passes: 2
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
L: if (true) {
|
||||||
|
a;
|
||||||
|
break L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while_if_break: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
loops: true,
|
||||||
|
passes: 2,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
while (a) {
|
||||||
|
if (b) if(c) d;
|
||||||
|
if (e) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
for(; a && (b && c && d, !e););
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,7 +4,7 @@ var uglify = require("../../");
|
||||||
|
|
||||||
describe("spidermonkey export/import sanity test", function() {
|
describe("spidermonkey export/import sanity test", function() {
|
||||||
it("should produce a functional build when using --self with spidermonkey", function (done) {
|
it("should produce a functional build when using --self with spidermonkey", function (done) {
|
||||||
this.timeout(20000);
|
this.timeout(60000);
|
||||||
|
|
||||||
var uglifyjs = '"' + process.argv[0] + '" bin/uglifyjs';
|
var uglifyjs = '"' + process.argv[0] + '" bin/uglifyjs';
|
||||||
var command = uglifyjs + " --self -cm --wrap SpiderUglify --dump-spidermonkey-ast | " +
|
var command = uglifyjs + " --self -cm --wrap SpiderUglify --dump-spidermonkey-ast | " +
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user