Index: pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart |
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart b/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart |
index 4bef70a003e05952146ff70e5438d5054ee2a783..aba10f4fc9967a4bee301471a4a6d7d3d50a6999 100644 |
--- a/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart |
+++ b/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart |
@@ -210,7 +210,47 @@ class LogicalRewriter extends RecursiveTransformer |
/// applied to the result of [visitExpression] conditionals will have been |
/// rewritten anyway. |
bool isBooleanValued(Expression e) { |
- return isTrue(e) || isFalse(e) || e is Not || e is LogicalOperator; |
+ return isTrue(e) || |
+ isFalse(e) || |
+ e is Not || |
+ e is LogicalOperator || |
+ e is ApplyBuiltinOperator && operatorReturnsBool(e.operator); |
+ } |
+ |
+ /// True if the given operator always returns `true` or `false`. |
+ bool operatorReturnsBool(BuiltinOperator operator) { |
+ switch (operator) { |
+ case BuiltinOperator.StrictEq: |
+ case BuiltinOperator.StrictNeq: |
+ case BuiltinOperator.LooseEq: |
+ case BuiltinOperator.LooseNeq: |
+ case BuiltinOperator.NumLt: |
+ case BuiltinOperator.NumLe: |
+ case BuiltinOperator.NumGt: |
+ case BuiltinOperator.NumGe: |
+ return true; |
+ default: |
+ return false; |
+ } |
+ } |
+ |
+ BuiltinOperator negateBuiltin(BuiltinOperator operator) { |
+ switch (operator) { |
+ case BuiltinOperator.StrictEq: return BuiltinOperator.StrictNeq; |
+ case BuiltinOperator.StrictNeq: return BuiltinOperator.StrictEq; |
+ case BuiltinOperator.LooseEq: return BuiltinOperator.LooseNeq; |
+ case BuiltinOperator.LooseNeq: return BuiltinOperator.LooseEq; |
+ |
+ // Because of NaN, these do not have a negated form. |
+ case BuiltinOperator.NumLt: |
+ case BuiltinOperator.NumLe: |
+ case BuiltinOperator.NumGt: |
+ case BuiltinOperator.NumGe: |
+ return null; |
+ |
+ default: |
+ return null; |
+ } |
} |
/// Rewrite an expression that was originally processed in a non-boolean |
@@ -257,6 +297,15 @@ class LogicalRewriter extends RecursiveTransformer |
} |
return e; |
} |
+ if (e is ApplyBuiltinOperator && polarity == false) { |
+ BuiltinOperator negated = negateBuiltin(e.operator); |
+ if (negated != null) { |
+ e.operator = negated; |
+ return visitExpression(e); |
+ } else { |
+ return new Not(visitExpression(e)); |
+ } |
+ } |
if (e is Conditional) { |
// Handle polarity by: !(x ? y : z) ==> x ? !y : !z |
// Rewrite individual branches now. The condition will be rewritten |