enhance conditionals (#4181)

This commit is contained in:
Alex Lam S.L
2020-10-05 08:55:37 +01:00
committed by GitHub
parent 813ac3ba96
commit 2dbe40b01b
2 changed files with 53 additions and 19 deletions

View File

@@ -7463,6 +7463,15 @@ merge(Compressor.prototype, {
|| node instanceof AST_Object;
}
function repeatable(compressor, node) {
if (node instanceof AST_Dot) return repeatable(compressor, node.expression);
if (node instanceof AST_Sub) {
return repeatable(compressor, node.expression) && repeatable(compressor, node.property);
}
if (node instanceof AST_Symbol) return true;
return !node.has_side_effects(compressor);
}
OPT(AST_Binary, function(self, compressor) {
function reversible() {
return self.left.is_constant()
@@ -7531,7 +7540,7 @@ merge(Compressor.prototype, {
if ((self.left.is_string(compressor) && self.right.is_string(compressor)) ||
(self.left.is_number(compressor) && self.right.is_number(compressor)) ||
(self.left.is_boolean(compressor) && self.right.is_boolean(compressor)) ||
can_self_compare(self.left) && self.left.equivalent_to(self.right)) {
repeatable(compressor, self.left) && self.left.equivalent_to(self.right)) {
self.operator = self.operator.slice(0, 2);
}
// XXX: intentionally falling down to the next case
@@ -8036,13 +8045,6 @@ merge(Compressor.prototype, {
}
return try_evaluate(compressor, self);
function can_self_compare(node) {
if (node instanceof AST_Dot) return can_self_compare(node.expression);
if (node instanceof AST_Sub) return can_self_compare(node.expression) && can_self_compare(node.property);
if (node instanceof AST_Symbol) return true;
return !node.has_side_effects(compressor);
}
function align(ref, op) {
switch (ref) {
case "-":
@@ -8504,14 +8506,13 @@ merge(Compressor.prototype, {
});
OPT(AST_Conditional, function(self, compressor) {
if (!compressor.option("conditionals")) return self;
// This looks like lift_sequences(), should probably be under "sequences"
if (self.condition instanceof AST_Sequence) {
if (compressor.option("sequences") && self.condition instanceof AST_Sequence) {
var expressions = self.condition.expressions.slice();
self.condition = expressions.pop();
expressions.push(self);
return make_sequence(self, expressions);
}
if (!compressor.option("conditionals")) return self;
var condition = self.condition.is_truthy() || self.condition.evaluate(compressor, true);
if (!condition) {
AST_Node.warn("Condition always false [{file}:{line},{col}]", self.start);
@@ -8532,15 +8533,19 @@ merge(Compressor.prototype, {
}
var consequent = self.consequent;
var alternative = self.alternative;
// x ? x : y => x || y
if (condition instanceof AST_SymbolRef
&& consequent instanceof AST_SymbolRef
&& condition.definition() === consequent.definition()) {
return make_node(AST_Binary, self, {
if (repeatable(compressor, condition)) {
// x ? x : y => x || y
if (condition.equivalent_to(consequent)) return make_node(AST_Binary, self, {
operator: "||",
left: condition,
right: alternative
});
right: alternative,
}).optimize(compressor);
// x ? y : x => x && y
if (condition.equivalent_to(alternative)) return make_node(AST_Binary, self, {
operator: "&&",
left: condition,
right: consequent,
}).optimize(compressor);
}
// if (foo) exp = something; else exp = something_else;
// |