Conditional/call optimization

foo ? bar(x) : bar(y)  ==>  bar(foo ? x : y)
This commit is contained in:
Mihai Bazon
2013-12-29 10:31:30 +02:00
parent aa9de76370
commit b521b4b926
3 changed files with 87 additions and 4 deletions

View File

@@ -2219,7 +2219,7 @@ merge(Compressor.prototype, {
* ==>
* exp = foo ? something : something_else;
*/
self = make_node(AST_Assign, self, {
return make_node(AST_Assign, self, {
operator: consequent.operator,
left: consequent.left,
right: make_node(AST_Conditional, self, {
@@ -2229,6 +2229,25 @@ merge(Compressor.prototype, {
})
});
}
if (consequent instanceof AST_Call
&& alternative.TYPE === consequent.TYPE
&& consequent.args.length == alternative.args.length
&& consequent.expression.equivalent_to(alternative.expression)) {
if (consequent.args.length == 0) {
return make_node(AST_Seq, self, {
car: self.condition,
cdr: consequent
});
}
if (consequent.args.length == 1) {
consequent.args[0] = make_node(AST_Conditional, self, {
condition: self.condition,
consequent: consequent.args[0],
alternative: alternative.args[0]
});
return consequent;
}
}
return self;
});

View File

@@ -141,3 +141,67 @@ ifs_6: {
x = foo || bar || baz || boo ? 20 : 10;
}
}
cond_1: {
options = {
conditionals: true
};
input: {
if (some_condition()) {
do_something(x);
} else {
do_something(y);
}
}
expect: {
do_something(some_condition() ? x : y);
}
}
cond_2: {
options = {
conditionals: true
};
input: {
if (some_condition()) {
x = new FooBar(1);
} else {
x = new FooBar(2);
}
}
expect: {
x = new FooBar(some_condition() ? 1 : 2);
}
}
cond_3: {
options = {
conditionals: true
};
input: {
if (some_condition()) {
new FooBar(1);
} else {
FooBar(2);
}
}
expect: {
some_condition() ? new FooBar(1) : FooBar(2);
}
}
cond_4: {
options = {
conditionals: true
};
input: {
if (some_condition()) {
do_something();
} else {
do_something();
}
}
expect: {
some_condition(), do_something();
}
}

View File

@@ -60,16 +60,16 @@ negate_iife_4: {
};
input: {
if ((function(){ return true })()) {
console.log(true);
foo(true);
} else {
console.log(false);
bar(false);
}
(function(){
console.log("something");
})();
}
expect: {
!function(){ return true }() ? console.log(false) : console.log(true), function(){
!function(){ return true }() ? bar(false) : foo(true), function(){
console.log("something");
}();
}