@@ -306,6 +306,15 @@ class LogicalRewriter extends RecursiveTransformer
306
306
node.elseExpression = tmp;
307
307
}
308
308
309
+ // x ? y : x ==> x && y
310
+ if (isSameVariable (node.condition, node.elseExpression)) {
311
+ return new LogicalOperator .and (node.condition, node.thenExpression);
312
+ }
313
+ // x ? x : y ==> x || y
314
+ if (isSameVariable (node.condition, node.thenExpression)) {
315
+ return new LogicalOperator .or (node.condition, node.elseExpression);
316
+ }
317
+
309
318
return node;
310
319
}
311
320
@@ -468,6 +477,16 @@ class LogicalRewriter extends RecursiveTransformer
468
477
e.elseExpression = (e.elseExpression as Not ).operand;
469
478
return new Not (e);
470
479
}
480
+
481
+ // x ? y : x ==> x && y
482
+ if (isSameVariable (e.condition, e.elseExpression)) {
483
+ return new LogicalOperator .and (e.condition, e.thenExpression);
484
+ }
485
+ // x ? x : y ==> x || y
486
+ if (isSameVariable (e.condition, e.thenExpression)) {
487
+ return new LogicalOperator .or (e.condition, e.elseExpression);
488
+ }
489
+
471
490
return e;
472
491
}
473
492
if (e is Constant && e.value.isBool) {
@@ -509,5 +528,19 @@ class LogicalRewriter extends RecursiveTransformer
509
528
return new LogicalOperator .or (e1, e2);
510
529
}
511
530
}
531
+
532
+ /// True if [e2] is known to return the same value as [e1]
533
+ /// (with no additional side effects) if evaluated immediately after [e1] .
534
+ ///
535
+ /// Concretely, this is true if [e1] and [e2] are uses of the same variable,
536
+ /// or if [e2] is a use of a variable assigned by [e1] .
537
+ bool isSameVariable (Expression e1, Expression e2) {
538
+ if (e1 is VariableUse ) {
539
+ return e2 is VariableUse && e1.variable == e2.variable;
540
+ } else if (e1 is Assign ) {
541
+ return e2 is VariableUse && e1.variable == e2.variable;
542
+ }
543
+ return false ;
544
+ }
512
545
}
513
546
0 commit comments