@@ -284,7 +284,9 @@ abstract class LoopingExprTree extends PostOrderTree {
284
284
285
285
abstract Label getLabel ( ) ;
286
286
287
- /** Whether this loop captures the `c` completion. */
287
+ abstract predicate entry ( AstNode node ) ;
288
+
289
+ /** Holds if this loop captures the `c` completion. */
288
290
predicate capturesLoopJumpCompletion ( LoopJumpCompletion c ) {
289
291
not c .hasLabel ( )
290
292
or
@@ -305,7 +307,7 @@ abstract class LoopingExprTree extends PostOrderTree {
305
307
or
306
308
c .( LoopJumpCompletion ) .isContinue ( ) and this .capturesLoopJumpCompletion ( c )
307
309
) and
308
- this .first ( succ )
310
+ this .entry ( succ )
309
311
}
310
312
311
313
override predicate last ( AstNode last , Completion c ) {
@@ -323,6 +325,8 @@ class LoopExprTree extends LoopingExprTree instanceof LoopExpr {
323
325
324
326
override Label getLabel ( ) { result = LoopExpr .super .getLabel ( ) }
325
327
328
+ override predicate entry ( AstNode node ) { this .first ( node ) }
329
+
326
330
override predicate first ( AstNode node ) { first ( this .getLoopBody ( ) , node ) }
327
331
}
328
332
@@ -331,6 +335,8 @@ class WhileExprTree extends LoopingExprTree instanceof WhileExpr {
331
335
332
336
override Label getLabel ( ) { result = WhileExpr .super .getLabel ( ) }
333
337
338
+ override predicate entry ( AstNode node ) { this .first ( node ) }
339
+
334
340
override predicate first ( AstNode node ) { first ( super .getCondition ( ) , node ) }
335
341
336
342
override predicate succ ( AstNode pred , AstNode succ , Completion c ) {
@@ -353,6 +359,39 @@ class WhileExprTree extends LoopingExprTree instanceof WhileExpr {
353
359
}
354
360
}
355
361
362
+ class ForExprTree extends LoopingExprTree instanceof ForExpr {
363
+ override BlockExpr getLoopBody ( ) { result = ForExpr .super .getLoopBody ( ) }
364
+
365
+ override Label getLabel ( ) { result = ForExpr .super .getLabel ( ) }
366
+
367
+ override predicate entry ( AstNode n ) { first ( super .getPat ( ) , n ) }
368
+
369
+ override predicate first ( AstNode node ) { first ( super .getIterable ( ) , node ) }
370
+
371
+ override predicate succ ( AstNode pred , AstNode succ , Completion c ) {
372
+ super .succ ( pred , succ , c )
373
+ or
374
+ last ( super .getIterable ( ) , pred , c ) and
375
+ first ( super .getPat ( ) , succ ) and
376
+ completionIsNormal ( c )
377
+ or
378
+ last ( super .getPat ( ) , pred , c ) and
379
+ c .( MatchCompletion ) .succeeded ( ) and
380
+ first ( this .getLoopBody ( ) , succ )
381
+ or
382
+ last ( super .getPat ( ) , pred , c ) and
383
+ c .( MatchCompletion ) .failed ( ) and
384
+ succ = this
385
+ }
386
+
387
+ override predicate last ( AstNode last , Completion c ) {
388
+ super .last ( last , c )
389
+ or
390
+ last ( super .getIterable ( ) , last , c ) and
391
+ not completionIsNormal ( c )
392
+ }
393
+ }
394
+
356
395
class MatchArmTree extends ControlFlowTree instanceof MatchArm {
357
396
override predicate propagatesAbnormal ( AstNode child ) { child = super .getExpr ( ) }
358
397
0 commit comments