#873 Fix conditionals optimizations with default compress options
This commit is contained in:
@@ -726,6 +726,32 @@ merge(Compressor.prototype, {
|
|||||||
return [ this ];
|
return [ this ];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
AST_Node.DEFMETHOD("is_constant", function(compressor){
|
||||||
|
// Accomodate when compress option evaluate=false
|
||||||
|
// as well as the common constant expressions !0 and !1
|
||||||
|
return this instanceof AST_Constant
|
||||||
|
|| (this instanceof AST_UnaryPrefix && this.operator == "!"
|
||||||
|
&& this.expression instanceof AST_Constant)
|
||||||
|
|| this.evaluate(compressor).length > 1;
|
||||||
|
});
|
||||||
|
// Obtain the constant value of an expression already known to be constant.
|
||||||
|
// Result only valid iff this.is_constant(compressor) is true.
|
||||||
|
AST_Node.DEFMETHOD("constant_value", function(compressor){
|
||||||
|
// Accomodate when option evaluate=false.
|
||||||
|
if (this instanceof AST_Constant) return this.value;
|
||||||
|
// Accomodate the common constant expressions !0 and !1 when option evaluate=false.
|
||||||
|
if (this instanceof AST_UnaryPrefix
|
||||||
|
&& this.operator == "!"
|
||||||
|
&& this.expression instanceof AST_Constant) {
|
||||||
|
return !this.expression.value;
|
||||||
|
}
|
||||||
|
var result = this.evaluate(compressor)
|
||||||
|
if (result.length > 1) {
|
||||||
|
return result[1];
|
||||||
|
}
|
||||||
|
// should never be reached
|
||||||
|
return undefined;
|
||||||
|
});
|
||||||
def(AST_Statement, function(){
|
def(AST_Statement, function(){
|
||||||
throw new Error(string_template("Cannot evaluate a statement [{file}:{line},{col}]", this.start));
|
throw new Error(string_template("Cannot evaluate a statement [{file}:{line},{col}]", this.start));
|
||||||
});
|
});
|
||||||
@@ -2427,32 +2453,48 @@ merge(Compressor.prototype, {
|
|||||||
alternative: alternative
|
alternative: alternative
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// x=y?1:1 --> x=1
|
// y?1:1 --> 1
|
||||||
if (consequent instanceof AST_Constant
|
if (consequent.is_constant(compressor)
|
||||||
&& alternative instanceof AST_Constant
|
&& alternative.is_constant(compressor)
|
||||||
&& consequent.equivalent_to(alternative)) {
|
&& consequent.equivalent_to(alternative)) {
|
||||||
|
var consequent_value = consequent.constant_value();
|
||||||
if (self.condition.has_side_effects(compressor)) {
|
if (self.condition.has_side_effects(compressor)) {
|
||||||
return AST_Seq.from_array([self.condition, make_node_from_constant(compressor, consequent.value, self)]);
|
return AST_Seq.from_array([self.condition, make_node_from_constant(compressor, consequent_value, self)]);
|
||||||
} else {
|
} else {
|
||||||
return make_node_from_constant(compressor, consequent.value, self);
|
return make_node_from_constant(compressor, consequent_value, self);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// x=y?true:false --> x=!!y
|
|
||||||
if (consequent instanceof AST_True
|
// y?true:false --> !!y
|
||||||
&& alternative instanceof AST_False) {
|
if (is_true(consequent) && is_false(alternative)) {
|
||||||
self.condition = self.condition.negate(compressor);
|
self.condition = self.condition.negate(compressor);
|
||||||
return make_node(AST_UnaryPrefix, self.condition, {
|
return make_node(AST_UnaryPrefix, self.condition, {
|
||||||
operator: "!",
|
operator: "!",
|
||||||
expression: self.condition
|
expression: self.condition
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// x=y?false:true --> x=!y
|
// y?false:true --> !y
|
||||||
if (consequent instanceof AST_False
|
if (is_false(consequent) && is_true(alternative)) {
|
||||||
&& alternative instanceof AST_True) {
|
|
||||||
return self.condition.negate(compressor)
|
return self.condition.negate(compressor)
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
|
|
||||||
|
// AST_True or !0
|
||||||
|
function is_true(node) {
|
||||||
|
return node instanceof AST_True
|
||||||
|
|| (node instanceof AST_UnaryPrefix
|
||||||
|
&& node.operator == "!"
|
||||||
|
&& node.expression instanceof AST_Constant
|
||||||
|
&& !node.expression.value);
|
||||||
|
}
|
||||||
|
// AST_False or !1
|
||||||
|
function is_false(node) {
|
||||||
|
return node instanceof AST_False
|
||||||
|
|| (node instanceof AST_UnaryPrefix
|
||||||
|
&& node.operator == "!"
|
||||||
|
&& node.expression instanceof AST_Constant
|
||||||
|
&& !!node.expression.value);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
OPT(AST_Boolean, function(self, compressor){
|
OPT(AST_Boolean, function(self, compressor){
|
||||||
|
|||||||
@@ -332,53 +332,247 @@ cond_7_1: {
|
|||||||
cond_8: {
|
cond_8: {
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
evaluate : true
|
evaluate : true,
|
||||||
|
booleans : false
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
var a;
|
var a;
|
||||||
// compress these
|
// compress these
|
||||||
a = condition ? true : false;
|
a = condition ? true : false;
|
||||||
|
|
||||||
a = !condition ? true : false;
|
a = !condition ? true : false;
|
||||||
|
|
||||||
a = condition() ? true : false;
|
a = condition() ? true : false;
|
||||||
|
|
||||||
|
a = condition ? !0 : !1;
|
||||||
|
a = !condition ? !null : !2;
|
||||||
|
a = condition() ? !0 : !-3.5;
|
||||||
|
|
||||||
if (condition) {
|
if (condition) {
|
||||||
a = true;
|
a = true;
|
||||||
} else {
|
} else {
|
||||||
a = false;
|
a = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (condition) {
|
||||||
|
a = !0;
|
||||||
|
} else {
|
||||||
|
a = !1;
|
||||||
|
}
|
||||||
|
|
||||||
a = condition ? false : true;
|
a = condition ? false : true;
|
||||||
|
|
||||||
a = !condition ? false : true;
|
a = !condition ? false : true;
|
||||||
|
|
||||||
a = condition() ? false : true;
|
a = condition() ? false : true;
|
||||||
|
|
||||||
|
a = condition ? !3 : !0;
|
||||||
|
a = !condition ? !2 : !0;
|
||||||
|
a = condition() ? !1 : !0;
|
||||||
|
|
||||||
if (condition) {
|
if (condition) {
|
||||||
a = false;
|
a = false;
|
||||||
} else {
|
} else {
|
||||||
a = true;
|
a = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (condition) {
|
||||||
|
a = !1;
|
||||||
|
} else {
|
||||||
|
a = !0;
|
||||||
|
}
|
||||||
|
|
||||||
// don't compress these
|
// don't compress these
|
||||||
a = condition ? 1 : false;
|
a = condition ? 1 : false;
|
||||||
|
|
||||||
a = !condition ? true : 0;
|
a = !condition ? true : 0;
|
||||||
|
|
||||||
a = condition ? 1 : 0;
|
a = condition ? 1 : 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a;
|
var a;
|
||||||
a = !!condition;
|
a = !!condition;
|
||||||
a = !condition;
|
a = !condition;
|
||||||
a = !!condition();
|
a = !!condition();
|
||||||
|
|
||||||
a = !!condition;
|
a = !!condition;
|
||||||
|
a = !condition;
|
||||||
|
a = !!condition();
|
||||||
|
|
||||||
|
a = !!condition;
|
||||||
|
a = !!condition;
|
||||||
|
|
||||||
a = !condition;
|
a = !condition;
|
||||||
a = !!condition;
|
a = !!condition;
|
||||||
a = !condition();
|
a = !condition();
|
||||||
|
|
||||||
a = !condition;
|
a = !condition;
|
||||||
|
a = !!condition;
|
||||||
|
a = !condition();
|
||||||
|
|
||||||
|
a = !condition;
|
||||||
|
a = !condition;
|
||||||
|
|
||||||
|
a = condition ? 1 : false;
|
||||||
|
a = condition ? 0 : true;
|
||||||
|
a = condition ? 1 : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cond_8b: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
evaluate : true,
|
||||||
|
booleans : true
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
// compress these
|
||||||
|
a = condition ? true : false;
|
||||||
|
a = !condition ? true : false;
|
||||||
|
a = condition() ? true : false;
|
||||||
|
|
||||||
|
a = condition ? !0 : !1;
|
||||||
|
a = !condition ? !null : !2;
|
||||||
|
a = condition() ? !0 : !-3.5;
|
||||||
|
|
||||||
|
if (condition) {
|
||||||
|
a = true;
|
||||||
|
} else {
|
||||||
|
a = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (condition) {
|
||||||
|
a = !0;
|
||||||
|
} else {
|
||||||
|
a = !1;
|
||||||
|
}
|
||||||
|
|
||||||
|
a = condition ? false : true;
|
||||||
|
a = !condition ? false : true;
|
||||||
|
a = condition() ? false : true;
|
||||||
|
|
||||||
|
a = condition ? !3 : !0;
|
||||||
|
a = !condition ? !2 : !0;
|
||||||
|
a = condition() ? !1 : !0;
|
||||||
|
|
||||||
|
if (condition) {
|
||||||
|
a = false;
|
||||||
|
} else {
|
||||||
|
a = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (condition) {
|
||||||
|
a = !1;
|
||||||
|
} else {
|
||||||
|
a = !0;
|
||||||
|
}
|
||||||
|
|
||||||
|
a = condition ? 1 : false;
|
||||||
|
a = !condition ? true : 0;
|
||||||
|
a = condition ? 1 : 0;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
a = !!condition;
|
||||||
|
a = !condition;
|
||||||
|
a = !!condition();
|
||||||
|
|
||||||
|
a = !!condition;
|
||||||
|
a = !condition;
|
||||||
|
a = !!condition();
|
||||||
|
|
||||||
|
a = !!condition;
|
||||||
|
a = !!condition;
|
||||||
|
|
||||||
|
a = !condition;
|
||||||
|
a = !!condition;
|
||||||
|
a = !condition();
|
||||||
|
|
||||||
|
a = !condition;
|
||||||
|
a = !!condition;
|
||||||
|
a = !condition();
|
||||||
|
|
||||||
|
a = !condition;
|
||||||
|
a = !condition;
|
||||||
|
|
||||||
|
a = condition ? 1 : !1;
|
||||||
|
a = condition ? 0 : !0;
|
||||||
|
a = condition ? 1 : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cond_8c: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
evaluate : false,
|
||||||
|
booleans : false
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
// compress these
|
||||||
|
a = condition ? true : false;
|
||||||
|
a = !condition ? true : false;
|
||||||
|
a = condition() ? true : false;
|
||||||
|
|
||||||
|
a = condition ? !0 : !1;
|
||||||
|
a = !condition ? !null : !2;
|
||||||
|
a = condition() ? !0 : !-3.5;
|
||||||
|
|
||||||
|
if (condition) {
|
||||||
|
a = true;
|
||||||
|
} else {
|
||||||
|
a = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (condition) {
|
||||||
|
a = !0;
|
||||||
|
} else {
|
||||||
|
a = !1;
|
||||||
|
}
|
||||||
|
|
||||||
|
a = condition ? false : true;
|
||||||
|
a = !condition ? false : true;
|
||||||
|
a = condition() ? false : true;
|
||||||
|
|
||||||
|
a = condition ? !3 : !0;
|
||||||
|
a = !condition ? !2 : !0;
|
||||||
|
a = condition() ? !1 : !0;
|
||||||
|
|
||||||
|
if (condition) {
|
||||||
|
a = false;
|
||||||
|
} else {
|
||||||
|
a = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (condition) {
|
||||||
|
a = !1;
|
||||||
|
} else {
|
||||||
|
a = !0;
|
||||||
|
}
|
||||||
|
|
||||||
|
a = condition ? 1 : false;
|
||||||
|
a = !condition ? true : 0;
|
||||||
|
a = condition ? 1 : 0;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
a = !!condition;
|
||||||
|
a = !condition;
|
||||||
|
a = !!condition();
|
||||||
|
|
||||||
|
a = !!condition;
|
||||||
|
a = !condition;
|
||||||
|
a = condition() ? !0 : !-3.5;
|
||||||
|
|
||||||
|
a = !!condition;
|
||||||
|
a = !!condition;
|
||||||
|
|
||||||
|
a = !condition;
|
||||||
|
a = !!condition;
|
||||||
|
a = !condition();
|
||||||
|
|
||||||
|
a = !condition;
|
||||||
|
a = !!condition;
|
||||||
|
a = !condition();
|
||||||
|
|
||||||
|
a = !condition;
|
||||||
|
a = !condition;
|
||||||
|
|
||||||
a = condition ? 1 : false;
|
a = condition ? 1 : false;
|
||||||
a = condition ? 0 : true;
|
a = condition ? 0 : true;
|
||||||
a = condition ? 1 : 0;
|
a = condition ? 1 : 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user