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();
}
This commit is contained in:
Mihai Bazon
2012-09-14 16:26:30 +03:00
parent 924aa58060
commit 5e83e7ec17
2 changed files with 49 additions and 25 deletions

View File

@@ -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 == "="