| Index: pkg/compiler/lib/src/ssa/builder_kernel.dart
|
| diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
|
| index ff2e4d96b3508b4a44a156fc607e742b26424f66..b9090525c09aa8dd1cd64040114562e23ab53625 100644
|
| --- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
|
| +++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
|
| @@ -1887,9 +1887,38 @@ class KernelSsaGraphBuilder extends ir.Visitor
|
| @override
|
| void visitLogicalExpression(ir.LogicalExpression logicalExpression) {
|
| SsaBranchBuilder brancher = new SsaBranchBuilder(this);
|
| - brancher.handleLogicalBinary(() => logicalExpression.left.accept(this),
|
| - () => logicalExpression.right.accept(this),
|
| - isAnd: logicalExpression.operator == '&&');
|
| + String operator = logicalExpression.operator;
|
| + // ir.LogicalExpression claims to allow '??' as an operator but currently
|
| + // that is expanded into a let-tree.
|
| + assert(operator == '&&' || operator == '||');
|
| + _handleLogicalExpression(logicalExpression.left,
|
| + () => logicalExpression.right.accept(this), brancher, operator);
|
| + }
|
| +
|
| + /// Optimizes logical binary expression where the left has the same logical
|
| + /// binary operator.
|
| + ///
|
| + /// This method transforms the operator by optimizing the case where [left] is
|
| + /// a logical "and" or logical "or". Then it uses [branchBuilder] to build the
|
| + /// graph for the optimized expression.
|
| + ///
|
| + /// For example, `(x && y) && z` is transformed into `x && (y && z)`:
|
| + ///
|
| + void _handleLogicalExpression(ir.Expression left, void visitRight(),
|
| + SsaBranchBuilder brancher, String operator) {
|
| + if (left is ir.LogicalExpression && left.operator == operator) {
|
| + ir.Expression innerLeft = left.left;
|
| + ir.Expression middle = left.right;
|
| + _handleLogicalExpression(
|
| + innerLeft,
|
| + () =>
|
| + _handleLogicalExpression(middle, visitRight, brancher, operator),
|
| + brancher,
|
| + operator);
|
| + } else {
|
| + brancher.handleLogicalBinary(() => left.accept(this), visitRight,
|
| + isAnd: operator == '&&');
|
| + }
|
| }
|
|
|
| @override
|
|
|