Merge branch 'master' into harmony-v2.8.5

This commit is contained in:
alexlamsl
2017-03-03 07:17:52 +08:00
11 changed files with 351 additions and 46 deletions

View File

@@ -182,6 +182,13 @@ merge(Compressor.prototype, {
var reduce_vars = rescan && compressor.option("reduce_vars");
var safe_ids = [];
push();
var suppressor = new TreeWalker(function(node) {
if (node instanceof AST_Symbol) {
var d = node.definition();
if (node instanceof AST_SymbolRef) d.references.push(node);
d.fixed = false;
}
});
var tw = new TreeWalker(function(node){
if (!(node instanceof AST_Directive || node instanceof AST_Constant)) {
node._squeezed = false;
@@ -244,9 +251,7 @@ merge(Compressor.prototype, {
return true;
}
if (node instanceof AST_ForIn) {
if (node.init instanceof AST_SymbolRef) {
node.init.definition().fixed = false;
}
node.init.walk(suppressor);
node.object.walk(tw);
push();
node.body.walk(tw);
@@ -485,8 +490,12 @@ merge(Compressor.prototype, {
// Constant single use vars can be replaced in any scope.
if (var_decl.value.is_constant()) {
var ctt = new TreeTransformer(function(node) {
if (node === ref)
return replace_var(node, ctt.parent(), true);
if (node === ref) {
var parent = ctt.parent();
if (!(parent instanceof AST_ForIn && parent.init === node)) {
return replace_var(node, parent, true);
}
}
});
stat.transform(ctt);
continue;
@@ -575,7 +584,7 @@ merge(Compressor.prototype, {
// Further optimize statement after substitution.
stat.reset_opt_flags(compressor);
compressor.warn("Replacing " + (is_constant ? "constant" : "variable") +
compressor.warn("Collapsing " + (is_constant ? "constant" : "variable") +
" " + var_name + " [{file}:{line},{col}]", node.start);
CHANGED = true;
return value;
@@ -1074,12 +1083,6 @@ merge(Compressor.prototype, {
def(AST_Conditional, function(compressor){
return this.consequent.is_string(compressor) && this.alternative.is_string(compressor);
});
def(AST_Call, function(compressor){
return compressor.option("unsafe")
&& this.expression instanceof AST_SymbolRef
&& this.expression.name == "String"
&& this.expression.undeclared();
});
})(function(node, func){
node.DEFMETHOD("is_string", func);
});
@@ -1899,16 +1902,18 @@ merge(Compressor.prototype, {
}
return node;
}
if (assign_as_unused
&& node instanceof AST_Assign
&& node.operator == "="
&& node.left instanceof AST_SymbolRef) {
var def = node.left.definition();
if ((drop_vars || !def.global)
&& !(def.id in in_use_ids)
&& self.variables.get(def.name) === def) {
return node.right;
if (assign_as_unused) {
var n = node;
while (n instanceof AST_Assign
&& n.operator == "="
&& n.left instanceof AST_SymbolRef) {
var def = n.left.definition();
if (def.id in in_use_ids
|| !drop_vars && def.global
|| self.variables.get(def.name) !== def) break;
n = n.right;
}
if (n !== node) return n;
}
if (node instanceof AST_For) {
descend(node, this);
@@ -2251,7 +2256,7 @@ merge(Compressor.prototype, {
}
} else {
// self instanceof AST_Do
return self.body;
return self;
}
}
if (self instanceof AST_While) {
@@ -2614,6 +2619,20 @@ merge(Compressor.prototype, {
});
OPT(AST_Call, function(self, compressor){
if (compressor.option("unused")
&& self.expression instanceof AST_Function
&& !self.expression.uses_arguments
&& !self.expression.uses_eval
&& self.args.length > self.expression.argnames.length) {
var end = self.expression.argnames.length;
for (var i = end, len = self.args.length; i < len; i++) {
var node = self.args[i].drop_side_effect_free(compressor);
if (node) {
self.args[end++] = node;
}
}
self.args.length = end;
}
if (compressor.option("unsafe")) {
var exp = self.expression;
if (exp instanceof AST_SymbolRef && exp.undeclared()) {
@@ -2815,6 +2834,12 @@ merge(Compressor.prototype, {
}
}
}
if (self.args.length == 0
&& self.expression instanceof AST_Function
&& self.expression.body[0] instanceof AST_Return
&& self.expression.body[0].value.is_constant()) {
return self.expression.body[0].value;
}
if (compressor.option("negate_iife")
&& compressor.parent() instanceof AST_SimpleStatement
&& is_iife_call(self)) {
@@ -3118,10 +3143,25 @@ merge(Compressor.prototype, {
}
}
}
if (self.operator == "+" && self.right instanceof AST_String
&& self.right.getValue() === "" && self.left instanceof AST_Binary
&& self.left.operator == "+" && self.left.is_string(compressor)) {
return self.left;
if (self.operator == "+") {
if (self.right instanceof AST_String
&& self.right.getValue() == ""
&& self.left.is_string(compressor)) {
return self.left;
}
if (self.left instanceof AST_String
&& self.left.getValue() == ""
&& self.right.is_string(compressor)) {
return self.right;
}
if (self.left instanceof AST_Binary
&& self.left.operator == "+"
&& self.left.left instanceof AST_String
&& self.left.left.getValue() == ""
&& self.right.is_string(compressor)) {
self.left = self.left.right;
return self.transform(compressor);
}
}
if (compressor.option("evaluate")) {
switch (self.operator) {