From 5e83e7ec17aca27ea818ce380a53c72ee221b900 Mon Sep 17 00:00:00 2001 From: Mihai Bazon Date: Fri, 14 Sep 2012 16:26:30 +0300 Subject: [PATCH] adding an imaginary "return undefined" can sometimes help function f() { if (foo) return x(); if (!bar) return y(); } ==> function f() { return foo ? x() : bar ? void 0 : y(); } --- lib/compress.js | 70 +++++++++++++++++++++++++++++++------------------ lib/output.js | 4 +++ 2 files changed, 49 insertions(+), 25 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index 52dc0113..3fd69402 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -190,33 +190,42 @@ function Compressor(options, false_by_default) { return MAP(statements, function(stat, i){ if (stat instanceof AST_If && stat.body instanceof AST_Return - && !stat.body.value && !stat.alternative && in_lambda) { - CHANGED = true; - if (i < last) { - var rest = statements.slice(i + 1); - var cond = stat.condition; - while (rest[0] instanceof AST_If - && rest[0].body instanceof AST_Return - && !rest[0].alternative) { - cond = make_node(AST_Binary, rest[0], { - operator: "||", - left: cond, - right: rest[0].condition - }); - rest.shift(); + if (!stat.body.value) { + CHANGED = true; + if (i < last) { + var rest = statements.slice(i + 1); + var cond = stat.condition; + while (rest[0] instanceof AST_If + && rest[0].body instanceof AST_Return + && !rest[0].alternative) { + cond = make_node(AST_Binary, rest[0], { + operator: "||", + left: cond, + right: rest[0].condition + }); + rest.shift(); + } + return MAP.last(make_node(AST_If, stat, { + condition: cond.negate(compressor), + body: make_node(AST_BlockStatement, stat, { + body: rest + }).optimize(compressor) + }).optimize(compressor)); + } else { + return make_node(AST_SimpleStatement, stat, { + body: stat.condition + }).optimize(compressor); } - return MAP.last(make_node(AST_If, stat, { - condition: cond.negate(compressor), - body: make_node(AST_BlockStatement, stat, { - body: rest - }).optimize(compressor) - }).optimize(compressor)); - } else { - return make_node(AST_SimpleStatement, stat, { - body: stat.condition - }).optimize(compressor); + } else if (i == last && last > 0 + && statements[last - 1] instanceof AST_If + && statements[last - 1].body instanceof AST_Return + && !statements[last - 1].alternative) { + CHANGED = true; + return MAP.splice([ stat, make_node(AST_Return, stat, { + value: make_node(AST_Undefined, stat) + })]); } } if (stat instanceof AST_If @@ -697,7 +706,7 @@ function Compressor(options, false_by_default) { } }); self.walk(tw); - if (vars_found > 0 && vardecl.length > 0) { + if (vars_found > 0 && vardecl.length > 1) { vardecl.forEach(function(v){ v.hoisted = true }); var node = make_node(AST_Var, self, { definitions: Object.keys(vars).map(function(name){ @@ -1338,6 +1347,17 @@ function Compressor(options, false_by_default) { return self.optimize(compressor); }); + SQUEEZE(AST_SymbolRef, function(self, compressor){ + return self.optimize(compressor); + }); + + AST_SymbolRef.DEFMETHOD("optimize", function(compressor){ + if (this.name == "undefined" && this.undeclared()) { + return make_node(AST_Undefined, this); + } + return this; + }); + var ASSIGN_OPS = [ '+', '-', '/', '*', '%', '>>', '<<', '>>>', '|', '^', '&' ]; AST_Assign.DEFMETHOD("optimize", function(compressor){ if (this.operator == "=" diff --git a/lib/output.js b/lib/output.js index a93f7387..602fa608 100644 --- a/lib/output.js +++ b/lib/output.js @@ -889,6 +889,10 @@ function OutputStream(options) { var def = self.definition(); output.print_name(def ? def.mangled_name || def.name : self.name); }); + DEFPRINT(AST_Undefined, function(self, output){ + // XXX: should add more options for this + output.print("void 0"); + }); DEFPRINT(AST_This, function(self, output){ output.print("this"); }); -- 2.34.1