compress AST_Arrow properly (#2170)

This commit is contained in:
Alex Lam S.L
2017-06-28 01:06:30 +08:00
committed by GitHub
parent ad139aa34d
commit 4d5aeeddfb
3 changed files with 303 additions and 21 deletions

View File

@@ -366,7 +366,7 @@ merge(Compressor.prototype, {
safe_ids = save_ids;
return true;
}
if (node instanceof AST_Function || node instanceof AST_Arrow) {
if (is_func_expr(node)) {
push();
var iife;
if (!node.name
@@ -564,6 +564,10 @@ merge(Compressor.prototype, {
return orig.length == 1 && orig[0] instanceof AST_SymbolLambda;
});
function is_func_expr(node) {
return node instanceof AST_Arrow || node instanceof AST_Function;
}
function is_lhs_read_only(lhs) {
if (lhs instanceof AST_SymbolRef) return lhs.definition().orig[0] instanceof AST_SymbolLambda;
if (lhs instanceof AST_PropAccess) {
@@ -707,7 +711,7 @@ merge(Compressor.prototype, {
function is_iife_call(node) {
if (node instanceof AST_Call && !(node instanceof AST_New)) {
return node.expression instanceof AST_Function || is_iife_call(node.expression);
return is_func_expr(node.expression) || is_iife_call(node.expression);
}
return false;
}
@@ -1320,6 +1324,7 @@ merge(Compressor.prototype, {
return false;
});
def(AST_Function, return_false);
def(AST_Arrow, return_false);
def(AST_UnaryPostfix, return_false);
def(AST_UnaryPrefix, function() {
return this.operator == "void";
@@ -1593,9 +1598,6 @@ merge(Compressor.prototype, {
def(AST_Lambda, function(){
throw def;
});
def(AST_Arrow, function() {
throw def;
});
def(AST_Class, function() {
throw def;
});
@@ -1649,8 +1651,7 @@ merge(Compressor.prototype, {
case "typeof":
// Function would be evaluated to an array and so typeof would
// incorrectly return 'object'. Hence making is a special case.
if (e instanceof AST_Function ||
e instanceof AST_Arrow) return typeof function(){};
if (is_func_expr(e)) return typeof function(){};
e = ev(e, compressor);
@@ -1822,6 +1823,9 @@ merge(Compressor.prototype, {
def(AST_Function, function(){
return basic_negation(this);
});
def(AST_Arrow, function(){
return basic_negation(this);
});
def(AST_UnaryPrefix, function(){
if (this.operator == "!")
return this.expression;
@@ -2568,7 +2572,7 @@ merge(Compressor.prototype, {
def(AST_This, return_null);
def(AST_Call, function(compressor, first_in_statement){
if (!this.has_pure_annotation(compressor) && compressor.pure_funcs(this)) {
if (this.expression instanceof AST_Function
if (is_func_expr(this.expression)
&& (!this.expression.name || !this.expression.name.definition().references.length)) {
var node = this.clone();
node.expression.process_expression(false, compressor);
@@ -3095,10 +3099,10 @@ merge(Compressor.prototype, {
});
if (compressor.option("unused")
&& simple_args
&& (fn instanceof AST_Function
&& (is_func_expr(fn)
|| compressor.option("reduce_vars")
&& fn instanceof AST_SymbolRef
&& (fn = fn.fixed_value()) instanceof AST_Function)
&& is_func_expr(fn = fn.fixed_value()))
&& !fn.uses_arguments
&& !fn.uses_eval) {
var pos = 0, last = 0;
@@ -3272,7 +3276,7 @@ merge(Compressor.prototype, {
if (self.args.length == 0) return make_node(AST_Function, self, {
argnames: [],
body: []
});
}).optimize(compressor);
if (all(self.args, function(x) {
return x instanceof AST_String;
})) {
@@ -3295,12 +3299,18 @@ merge(Compressor.prototype, {
var fun;
ast.walk(new TreeWalker(function(node) {
if (fun) return true;
if (node instanceof AST_Function) {
if (is_func_expr(node)) {
fun = node;
return true;
}
}));
if (!fun) return self;
if (fun.body instanceof AST_Node) {
fun.body = [
make_node(AST_Return, fun.body, {
value: fun.body
})
];
}
var args = fun.argnames.map(function(arg, i) {
return make_node(AST_String, self.args[i], {
value: arg.print_to_string()
@@ -3324,7 +3334,14 @@ merge(Compressor.prototype, {
}
}
}
var stat = fn instanceof AST_Function && fn.body[0];
var stat = is_func_expr(fn) && fn.body;
if (stat instanceof AST_Node) {
stat = make_node(AST_Return, stat, {
value: stat
});
} else if (stat) {
stat = stat[0];
}
if (compressor.option("inline") && stat instanceof AST_Return) {
var value = stat.value;
if (!value || value.is_constant_expression()) {
@@ -3332,10 +3349,10 @@ merge(Compressor.prototype, {
return make_sequence(self, args).transform(compressor);
}
}
if (exp instanceof AST_Function && !exp.is_generator && !exp.async) {
if (is_func_expr(exp) && !exp.is_generator && !exp.async) {
if (compressor.option("inline")
&& !exp.name
&& exp.body.length == 1
&& (exp.body instanceof AST_Node || exp.body.length == 1)
&& !exp.uses_arguments
&& !exp.uses_eval
&& simple_args
@@ -3385,6 +3402,13 @@ merge(Compressor.prototype, {
value: value
}));
var body = fn.transform(compressor).body;
if (body instanceof AST_Node) {
body = [
make_node(AST_Return, body, {
value: body
})
];
}
if (body.length == 0) return make_node(AST_Undefined, self);
if (body.length == 1 && body[0] instanceof AST_Return) {
value = body[0].value;
@@ -3411,7 +3435,7 @@ merge(Compressor.prototype, {
if (value !== self) return value;
}
}
if (compressor.option("side_effects") && all(exp.body, is_empty)) {
if (compressor.option("side_effects") && !(exp.body instanceof AST_Node) && all(exp.body, is_empty)) {
var args = self.args.concat(make_node(AST_Undefined, self));
return make_sequence(self, args).transform(compressor);
}
@@ -4085,7 +4109,7 @@ merge(Compressor.prototype, {
d.fixed = fixed = make_node(AST_Function, fixed, fixed);
}
if (compressor.option("unused")
&& fixed instanceof AST_Function
&& is_func_expr(fixed)
&& d.references.length == 1
&& !(d.scope.uses_arguments && d.orig[0] instanceof AST_SymbolFunarg)
&& !d.scope.uses_eval