@@ -613,6 +613,73 @@ main() {
613613 });
614614 });
615615
616+ test ('whileStatement_conditionBegin() un-promotes' , () {
617+ var h = _Harness ();
618+ var x = h.addVar ('x' , 'int?' );
619+ h.run ((flow) {
620+ h.declare (x, initialized: true );
621+ h.promote (x, 'int' );
622+ expect (flow.promotedType (x).type, 'int' );
623+ flow.whileStatement_conditionBegin ({x});
624+ expect (flow.promotedType (x), isNull);
625+ flow.whileStatement_bodyBegin (_Statement (), _Expression ());
626+ flow.whileStatement_end ();
627+ });
628+ });
629+
630+ test ('whileStatement_conditionBegin() handles not-yet-seen variables' , () {
631+ var h = _Harness ();
632+ var x = h.addVar ('x' , 'int?' );
633+ var y = h.addVar ('y' , 'int?' );
634+ h.run ((flow) {
635+ h.declare (y, initialized: true );
636+ h.promote (y, 'int' );
637+ flow.whileStatement_conditionBegin ({x});
638+ flow.add (x, assigned: true );
639+ flow.whileStatement_bodyBegin (_Statement (), _Expression ());
640+ flow.whileStatement_end ();
641+ });
642+ });
643+
644+ test ('whileStatement_bodyBegin() promotes' , () {
645+ var h = _Harness ();
646+ var x = h.addVar ('x' , 'int?' );
647+ h.run ((flow) {
648+ h.declare (x, initialized: true );
649+ flow.whileStatement_conditionBegin ({});
650+ flow.whileStatement_bodyBegin (_Statement (), h.notNull (x)());
651+ expect (flow.promotedType (x).type, 'int' );
652+ flow.whileStatement_end ();
653+ });
654+ });
655+
656+ test ('whileStatement_end() joins break and condition-false states' , () {
657+ // To test that the states are properly joined, we have three variables:
658+ // x, y, and z. We promote x and y in the break path, and x and z in the
659+ // condition-false path. After the loop, only x should be promoted.
660+ var h = _Harness ();
661+ var x = h.addVar ('x' , 'int?' );
662+ var y = h.addVar ('y' , 'int?' );
663+ var z = h.addVar ('z' , 'int?' );
664+ h.run ((flow) {
665+ h.declare (x, initialized: true );
666+ h.declare (y, initialized: true );
667+ h.declare (z, initialized: true );
668+ var stmt = _Statement ();
669+ flow.whileStatement_conditionBegin ({});
670+ flow.whileStatement_bodyBegin (stmt, h.or (h.eqNull (x), h.eqNull (z))());
671+ h.if_ (h.expr, () {
672+ h.promote (x, 'int' );
673+ h.promote (y, 'int' );
674+ flow.handleBreak (stmt);
675+ });
676+ flow.whileStatement_end ();
677+ expect (flow.promotedType (x).type, 'int' );
678+ expect (flow.promotedType (y), isNull);
679+ expect (flow.promotedType (z), isNull);
680+ });
681+ });
682+
616683 test ('Infinite loop does not implicitly assign variables' , () {
617684 var h = _Harness ();
618685 var x = h.addVar ('x' , 'int' );
0 commit comments