Chromium Code Reviews| 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..2ed673b129dd9f81a3491bd7a363ea733d5c825f 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,44 @@ 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); |
|
Kevin Millikin (Google)
2015/06/12 12:19:10
I like parens around the && subexpression. I usua
asgerf
2015/06/15 09:26:18
What if we just split the line like this? Then the
Kevin Millikin (Google)
2015/06/15 10:24:09
It's OK this way.
|
| + } |
| + |
| + /// 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 +294,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 |