diff options
Diffstat (limited to 'lib/compress.js')
-rw-r--r-- | lib/compress.js | 65 |
1 files changed, 55 insertions, 10 deletions
diff --git a/lib/compress.js b/lib/compress.js index a46cd42b..ffc19b25 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -49,6 +49,7 @@ function Compressor(options, false_by_default) { TreeTransformer.call(this, this.before, this.after); this.options = defaults(options, { arguments : !false_by_default, + arrows : !false_by_default, assignments : !false_by_default, booleans : !false_by_default, collapse_vars : !false_by_default, @@ -1372,7 +1373,8 @@ merge(Compressor.prototype, { function is_iife_call(node) { if (node.TYPE != "Call") return false; - return is_function(node.expression) || is_iife_call(node.expression); + var exp = node.expression; + return exp instanceof AST_AsyncFunction || exp instanceof AST_Function || is_iife_call(exp); } function is_undeclared_ref(node) { @@ -3573,12 +3575,20 @@ merge(Compressor.prototype, { return map; } - AST_Lambda.DEFMETHOD("first_statement", function() { - var body = this.body; + function skip_directives(body) { for (var i = 0; i < body.length; i++) { var stat = body[i]; if (!(stat instanceof AST_Directive)) return stat; } + } + AST_Arrow.DEFMETHOD("first_statement", function() { + if (this.value) return make_node(AST_Return, this.value, { + value: this.value + }); + return skip_directives(this.body); + }); + AST_Lambda.DEFMETHOD("first_statement", function() { + return skip_directives(this.body); }); function try_evaluate(compressor, node) { @@ -4170,6 +4180,9 @@ merge(Compressor.prototype, { def(AST_Statement, function() { throw new Error("Cannot negate a statement"); }); + def(AST_Arrow, function() { + return basic_negation(this); + }); def(AST_AsyncFunction, function() { return basic_negation(this); }); @@ -4568,6 +4581,10 @@ merge(Compressor.prototype, { result = false; return true; } + if (node instanceof AST_This) { + if (scopes.length == 0 && self instanceof AST_Arrow) result = false; + return true; + } })); return result; }); @@ -4651,6 +4668,28 @@ merge(Compressor.prototype, { return trim_block(self); }); + OPT(AST_Arrow, function(self, compressor) { + if (!compressor.option("arrows")) return self; + if (self.value) { + var value = self.value; + if (is_undefined(value, compressor)) { + self.value = null; + } else if (value instanceof AST_UnaryPrefix && value.operator == "void") { + self.body.push(make_node(AST_SimpleStatement, value, { + body: value.expression + })); + self.value = null; + } + } else if (self.body.length == 1) { + var stat = self.body[0]; + if (stat instanceof AST_Return && stat.value) { + self.body.pop(); + self.value = stat.value; + } + } + return self; + }); + OPT(AST_Function, function(self, compressor) { self.body = tighten_body(self.body, compressor); if (compressor.option("inline")) for (var i = 0; i < self.body.length; i++) { @@ -6316,6 +6355,7 @@ merge(Compressor.prototype, { })) return this; return make_sequence(this, values.map(convert_spread)); }); + def(AST_Arrow, return_null); def(AST_Assign, function(compressor) { var left = this.left; if (left instanceof AST_PropAccess) { @@ -7702,7 +7742,7 @@ merge(Compressor.prototype, { } } var fn = exp instanceof AST_SymbolRef ? exp.fixed_value() : exp; - var is_func = fn instanceof AST_Defun || fn instanceof AST_Function; + var is_func = fn instanceof AST_Arrow || fn instanceof AST_Defun || fn instanceof AST_Function; var stat = is_func && fn.first_statement(); var can_inline = is_func && compressor.option("inline") @@ -7772,10 +7812,11 @@ merge(Compressor.prototype, { } if (compressor.option("side_effects") && all(fn.body, is_empty) + && (fn !== exp || fn_name_unused(fn, compressor)) + && !(fn instanceof AST_Arrow && fn.value) && all(fn.argnames, function(argname) { return !(argname instanceof AST_Destructured); - }) - && (fn !== exp || fn_name_unused(fn, compressor))) { + })) { var args = self.args.map(function(arg) { return arg instanceof AST_Spread ? make_node(AST_Array, arg, { elements: [ arg ], @@ -7814,9 +7855,11 @@ merge(Compressor.prototype, { function can_flatten_body(stat) { var len = fn.body.length; - if (compressor.option("inline") < 3) { - return len == 1 && return_value(stat); + if (len < 2) { + stat = return_value(stat); + if (stat) return stat; } + if (compressor.option("inline") < 3) return false; stat = null; for (var i = 0; i < len; i++) { var line = fn.body[i]; @@ -9833,7 +9876,7 @@ merge(Compressor.prototype, { && expr instanceof AST_SymbolRef && is_arguments(def = expr.definition()) && prop instanceof AST_Number - && (fn = expr.scope.resolve()) === find_lambda() + && (fn = def.scope) === find_lambda() && !(assigned && fn.uses_arguments === "d")) { var index = prop.value; if (parent instanceof AST_UnaryPrefix && parent.operator == "delete") { @@ -9936,6 +9979,7 @@ merge(Compressor.prototype, { while (p = compressor.parent(i++)) { if (p instanceof AST_Lambda) { if (p instanceof AST_Accessor) return; + if (p instanceof AST_Arrow) continue; fn_parent = compressor.parent(i); return p; } @@ -9943,13 +9987,14 @@ merge(Compressor.prototype, { } }); + AST_Arrow.DEFMETHOD("contains_this", return_false); AST_Scope.DEFMETHOD("contains_this", function() { var result; var self = this; self.walk(new TreeWalker(function(node) { if (result) return true; if (node instanceof AST_This) return result = true; - if (node !== self && node instanceof AST_Scope) return true; + if (node !== self && node instanceof AST_Scope && !(node instanceof AST_Arrow)) return true; })); return result; }); |