@@ -12291,10 +12291,14 @@ main() {
1229112291
1229212292 group ('Try/finally layering order:' , () {
1229312293 group ('Local variables:' , () {
12294- test ('When disabled, promotions in `finally` applied first' , () {
12295- h.disableSoundFlowAnalysis ();
12296- var x = Var ('x' );
12297- var y = Var ('y' );
12294+ late Var x, y;
12295+
12296+ setUp (() {
12297+ x = Var ('x' );
12298+ y = Var ('y' );
12299+ });
12300+
12301+ void checkPromotionsAfterTryFinally (List <ProtoStatement > expectations) {
1229812302 h.run ([
1229912303 declare (x, initializer: expr ('Object' )),
1230012304 declare (y, initializer: expr ('Object' )),
@@ -12314,6 +12318,13 @@ main() {
1231412318 checkPromoted (x, 'int' ),
1231512319 checkPromoted (y, 'num' ),
1231612320 ]),
12321+ ...expectations,
12322+ ]);
12323+ }
12324+
12325+ test ('When disabled, promotions in `finally` applied first' , () {
12326+ h.disableSoundFlowAnalysis ();
12327+ checkPromotionsAfterTryFinally ([
1231712328 // After the try/finally, both `x` and `y` are fully promoted to
1231812329 // `int`. But since the promotions from the `try` block are layered
1231912330 // over the promotions from the `finally` block, `x` has promotion
@@ -12324,27 +12335,7 @@ main() {
1232412335 });
1232512336
1232612337 test ('When enabled, promotions in `try` applied first' , () {
12327- var x = Var ('x' );
12328- var y = Var ('y' );
12329- h.run ([
12330- declare (x, initializer: expr ('Object' )),
12331- declare (y, initializer: expr ('Object' )),
12332- try_ ([
12333- x.as_ ('num' ),
12334- y.as_ ('int' ),
12335- checkPromoted (x, 'num' ),
12336- checkPromoted (y, 'int' ),
12337- ]).finally_ ([
12338- // Neither `x` nor `y` is promoted at this point, because in
12339- // principle an exception could have occurred at any point in the
12340- // `try` block.
12341- checkNotPromoted (x),
12342- checkNotPromoted (y),
12343- x.as_ ('int' ),
12344- y.as_ ('num' ),
12345- checkPromoted (x, 'int' ),
12346- checkPromoted (y, 'num' ),
12347- ]),
12338+ checkPromotionsAfterTryFinally ([
1234812339 // After the try/finally, both `x` and `y` are fully promoted to
1234912340 // `int`. But since the promotions from the `finally` block are
1235012341 // layered over the promotions from the `try` block, `x` has
@@ -12357,11 +12348,15 @@ main() {
1235712348 });
1235812349
1235912350 group ('Fields of unmodified local variables:' , () {
12360- test ('When disabled, promotions in `finally` applied first' , () {
12361- h.disableSoundFlowAnalysis ();
12351+ late Var x, y;
12352+
12353+ setUp (() {
12354+ x = Var ('x' );
12355+ y = Var ('y' );
12356+ });
12357+
12358+ void checkPromotionsAfterTryFinally (List <ProtoStatement > expectations) {
1236212359 h.addMember ('C' , '_f' , 'Object' , promotable: true );
12363- var x = Var ('x' );
12364- var y = Var ('y' );
1236512360 h.run ([
1236612361 declare (x, initializer: expr ('C' )),
1236712362 declare (y, initializer: expr ('C' )),
@@ -12381,6 +12376,13 @@ main() {
1238112376 checkPromoted (x.property ('_f' ), 'int' ),
1238212377 checkPromoted (y.property ('_f' ), 'num' ),
1238312378 ]),
12379+ ...expectations,
12380+ ]);
12381+ }
12382+
12383+ test ('When disabled, promotions in `finally` applied first' , () {
12384+ h.disableSoundFlowAnalysis ();
12385+ checkPromotionsAfterTryFinally ([
1238412386 // After the try/finally, both `x._f` and `y._f` are fully promoted
1238512387 // to `int`. But since the promotions from the `try` block are
1238612388 // layered over the promotions from the `finally` block, `x._f` has
@@ -12392,28 +12394,7 @@ main() {
1239212394 });
1239312395
1239412396 test ('When enabled, promotions in `try` applied first' , () {
12395- h.addMember ('C' , '_f' , 'Object' , promotable: true );
12396- var x = Var ('x' );
12397- var y = Var ('y' );
12398- h.run ([
12399- declare (x, initializer: expr ('C' )),
12400- declare (y, initializer: expr ('C' )),
12401- try_ ([
12402- x.property ('_f' ).as_ ('num' ),
12403- y.property ('_f' ).as_ ('int' ),
12404- checkPromoted (x.property ('_f' ), 'num' ),
12405- checkPromoted (y.property ('_f' ), 'int' ),
12406- ]).finally_ ([
12407- // Neither `x._f` nor `y._f` is promoted at this point, because in
12408- // principle an exception could have occurred at any point in the
12409- // `try` block.
12410- checkNotPromoted (x.property ('_f' )),
12411- checkNotPromoted (y.property ('_f' )),
12412- x.property ('_f' ).as_ ('int' ),
12413- y.property ('_f' ).as_ ('num' ),
12414- checkPromoted (x.property ('_f' ), 'int' ),
12415- checkPromoted (y.property ('_f' ), 'num' ),
12416- ]),
12397+ checkPromotionsAfterTryFinally ([
1241712398 // After the try/finally, both `x._f` and `y._f` are fully promoted
1241812399 // to `int`. But since the promotions from the `finally` block are
1241912400 // layered over the promotions from the `try` block, `x._f` has
@@ -12426,11 +12407,15 @@ main() {
1242612407 });
1242712408
1242812409 group ('Fields of local variables modified in try clause:' , () {
12429- test ('When disabled, promotions in `try` applied first' , () {
12430- h.disableSoundFlowAnalysis ();
12410+ late Var x, y;
12411+
12412+ setUp (() {
12413+ x = Var ('x' );
12414+ y = Var ('y' );
12415+ });
12416+
12417+ void checkPromotionsAfterTryFinally (List <ProtoStatement > expectations) {
1243112418 h.addMember ('C' , '_f' , 'Object' , promotable: true );
12432- var x = Var ('x' );
12433- var y = Var ('y' );
1243412419 h.run ([
1243512420 declare (x, initializer: expr ('C' )),
1243612421 declare (y, initializer: expr ('C' )),
@@ -12452,6 +12437,13 @@ main() {
1245212437 checkPromoted (x.property ('_f' ), 'int' ),
1245312438 checkPromoted (y.property ('_f' ), 'num' ),
1245412439 ]),
12440+ ...expectations,
12441+ ]);
12442+ }
12443+
12444+ test ('When disabled, promotions in `try` applied first' , () {
12445+ h.disableSoundFlowAnalysis ();
12446+ checkPromotionsAfterTryFinally ([
1245512447 // After the try/finally, both `x._f` and `y._f` are fully promoted
1245612448 // to `int`. But since the promotions from the `finally` block are
1245712449 // layered over the promotions from the `try` block, `x._f` has
@@ -12463,30 +12455,7 @@ main() {
1246312455 });
1246412456
1246512457 test ('When enabled, promotions in `try` applied first' , () {
12466- h.addMember ('C' , '_f' , 'Object' , promotable: true );
12467- var x = Var ('x' );
12468- var y = Var ('y' );
12469- h.run ([
12470- declare (x, initializer: expr ('C' )),
12471- declare (y, initializer: expr ('C' )),
12472- try_ ([
12473- x.write (expr ('C' )),
12474- y.write (expr ('C' )),
12475- x.property ('_f' ).as_ ('num' ),
12476- y.property ('_f' ).as_ ('int' ),
12477- checkPromoted (x.property ('_f' ), 'num' ),
12478- checkPromoted (y.property ('_f' ), 'int' ),
12479- ]).finally_ ([
12480- // Neither `x._f` nor `y._f` is promoted at this point, because in
12481- // principle an exception could have occurred at any point in the
12482- // `try` block.
12483- checkNotPromoted (x.property ('_f' )),
12484- checkNotPromoted (y.property ('_f' )),
12485- x.property ('_f' ).as_ ('int' ),
12486- y.property ('_f' ).as_ ('num' ),
12487- checkPromoted (x.property ('_f' ), 'int' ),
12488- checkPromoted (y.property ('_f' ), 'num' ),
12489- ]),
12458+ checkPromotionsAfterTryFinally ([
1249012459 // After the try/finally, both `x._f` and `y._f` are fully promoted
1249112460 // to `int`. But since the promotions from the `finally` block are
1249212461 // layered over the promotions from the `try` block, `x._f` has
0 commit comments