@@ -147,23 +147,15 @@ class BlockExprTree extends StandardPostOrderTree, BlockExpr {
147147 override predicate propagatesAbnormal ( AstNode child ) { child = this .getChildNode ( _) }
148148}
149149
150- class BreakExprTree extends PostOrderTree , BreakExpr {
151- override predicate propagatesAbnormal ( AstNode child ) { child = this .getExpr ( ) }
152-
153- override predicate first ( AstNode node ) {
154- first ( this .getExpr ( ) , node )
155- or
156- not this .hasExpr ( ) and node = this
157- }
150+ class BreakExprTree extends StandardPostOrderTree , BreakExpr {
151+ override AstNode getChildNode ( int i ) { i = 0 and result = this .getExpr ( ) }
158152
159153 override predicate last ( AstNode last , Completion c ) { none ( ) }
160154
161155 override predicate succ ( AstNode pred , AstNode succ , Completion c ) {
162- last ( super .getExpr ( ) , pred , c ) and succ = this
156+ super .succ ( pred , succ , c )
163157 or
164- pred = this and
165- c .isValidFor ( pred ) and
166- succ = this .getTarget ( )
158+ pred = this and c .isValidFor ( pred ) and succ = this .getTarget ( )
167159 }
168160}
169161
@@ -325,7 +317,7 @@ class LetStmtTree extends PreOrderTree, LetStmt {
325317 not this .hasInitializer ( )
326318 or
327319 // Edge from end of initializer to pattern.
328- last ( this .getInitializer ( ) , pred , c ) and first ( this .getPat ( ) , succ )
320+ last ( this .getInitializer ( ) , pred , c ) and first ( this .getPat ( ) , succ ) and completionIsNormal ( c )
329321 or
330322 // Edge from failed pattern to `else` branch.
331323 last ( this .getPat ( ) , pred , c ) and
@@ -502,14 +494,21 @@ class MatchExprTree extends PostOrderTree instanceof MatchExpr {
502494 override predicate first ( AstNode node ) { first ( super .getExpr ( ) , node ) }
503495
504496 override predicate succ ( AstNode pred , AstNode succ , Completion c ) {
505- // Edge from the scrutinee to the first arm.
497+ // Edge from the scrutinee to the first arm or to the match expression if no arms .
506498 last ( super .getExpr ( ) , pred , c ) and
507- first ( super .getArm ( 0 ) .getPat ( ) , succ ) and
499+ (
500+ first ( super .getArm ( 0 ) .getPat ( ) , succ )
501+ or
502+ not exists ( super .getArm ( 0 ) ) and succ = this
503+ ) and
508504 completionIsNormal ( c )
509505 or
510- // Edge from a failed match/ guard in one arm to the beginning of the next arm.
506+ // Edge from a failed pattern or guard in one arm to the beginning of the next arm.
511507 exists ( int i |
512- last ( super .getArm ( i ) , pred , c ) and
508+ (
509+ last ( super .getArm ( i ) .getPat ( ) , pred , c ) or
510+ last ( super .getArm ( i ) .getGuard ( ) .getCondition ( ) , pred , c )
511+ ) and
513512 first ( super .getArm ( i + 1 ) , succ ) and
514513 c .( ConditionalCompletion ) .failed ( )
515514 )
@@ -521,10 +520,7 @@ class MatchExprTree extends PostOrderTree instanceof MatchExpr {
521520
522521class MethodCallExprTree extends StandardPostOrderTree , MethodCallExpr {
523522 override AstNode getChildNode ( int i ) {
524- i = 0 and
525- result = this .getReceiver ( )
526- or
527- result = this .getArgList ( ) .getArg ( i + 1 )
523+ if i = 0 then result = this .getReceiver ( ) else result = this .getArgList ( ) .getArg ( i - 1 )
528524 }
529525}
530526
@@ -605,89 +601,48 @@ class YeetExprTree extends StandardPostOrderTree instanceof YeetExpr {
605601 * `OrPat`s and `IdentPat`s.
606602 */
607603module PatternTrees {
608- abstract class PreOrderPatTree extends PreOrderTree {
604+ abstract class StandardPatTree extends StandardTree {
609605 abstract Pat getPat ( int i ) ;
610606
611- private Pat getPatRanked ( int i ) {
607+ Pat getPatRanked ( int i ) {
612608 result = rank [ i + 1 ] ( Pat pat , int j | pat = this .getPat ( j ) | pat order by j )
613609 }
614610
615- override predicate propagatesAbnormal ( AstNode child ) { child = this .getPatRanked ( _) }
611+ override AstNode getChildNode ( int i ) { result = this .getPat ( i ) }
612+ }
616613
614+ abstract class PreOrderPatTree extends StandardPatTree , StandardPreOrderTree {
617615 override predicate succ ( AstNode pred , AstNode succ , Completion c ) {
618- pred = this and
619- completionIsValidFor ( c , this ) and
620616 c .( MatchCompletion ) .succeeded ( ) and
621- first ( this .getPatRanked ( 0 ) , succ )
622- or
623- exists ( int i | last ( this .getPatRanked ( i ) , pred , c ) |
624- // Edge from successful pattern to the next
625- c .( MatchCompletion ) .succeeded ( ) and
626- first ( this .getPatRanked ( i + 1 ) , succ )
617+ (
618+ StandardPatTree .super .succ ( pred , succ , c )
619+ or
620+ pred = this and first ( this .getFirstChildNode ( ) , succ ) and completionIsValidFor ( c , this )
627621 )
628622 }
629623
630624 override predicate last ( AstNode node , Completion c ) {
631- node = this and
632- completionIsValidFor ( c , this ) and
633- c .( MatchCompletion ) .failed ( )
625+ super .last ( node , c )
634626 or
635- exists ( int i | last ( this .getPatRanked ( i ) , node , c ) |
636- c .( MatchCompletion ) .failed ( )
637- or
638- not exists ( this .getPatRanked ( i + 1 ) ) and
639- completionIsNormal ( c )
640- )
627+ c .( MatchCompletion ) .failed ( ) and
628+ completionIsValidFor ( c , this ) and
629+ ( node = this or last ( this .getPatRanked ( _) , node , c ) )
641630 }
642631 }
643632
644- abstract class PostOrderPatTree extends PostOrderTree {
645- abstract Pat getPat ( int i ) ;
646-
647- private Pat getPatRanked ( int i ) {
648- result = rank [ i + 1 ] ( Pat pat , int j | pat = this .getPat ( j ) | pat order by j )
649- }
650-
651- override predicate propagatesAbnormal ( AstNode child ) { child = this .getPatRanked ( _) }
652-
653- override predicate first ( AstNode node ) {
654- first ( this .getPat ( 0 ) , node )
655- or
656- not exists ( this .getPat ( _) ) and
657- node = this
658- }
659-
660- override predicate succ ( AstNode pred , AstNode succ , Completion c ) {
661- exists ( int i | last ( this .getPat ( i ) , pred , c ) |
662- // Edge from unsuccessful pattern to the next
663- c .( MatchCompletion ) .failed ( ) and
664- first ( this .getPat ( i + 1 ) , succ )
665- or
666- // Edge from successful pattern to this
667- c .( MatchCompletion ) .succeeded ( ) and
668- succ = this
669- or
670- // Edge from last pattern to this
671- not exists ( this .getPat ( i + 1 ) ) and
672- succ = this and
673- completionIsNormal ( c )
674- )
675- }
676- }
633+ abstract class PostOrderPatTree extends StandardPatTree , StandardPostOrderTree { }
677634
678635 class IdentPatTree extends PostOrderPatTree , IdentPat {
679636 override Pat getPat ( int i ) { i = 0 and result = this .getPat ( ) }
680637
681638 override predicate last ( AstNode node , Completion c ) {
682639 super .last ( node , c )
683640 or
684- last ( this .getPat ( ) , node , c ) and
685- c .( MatchCompletion ) .failed ( )
641+ last ( this .getPat ( ) , node , c ) and c .( MatchCompletion ) .failed ( )
686642 }
687643
688644 override predicate succ ( AstNode pred , AstNode succ , Completion c ) {
689- super .succ ( pred , succ , c ) and
690- not ( succ = this and c .( MatchCompletion ) .failed ( ) )
645+ super .succ ( pred , succ , c ) and c .( MatchCompletion ) .succeeded ( )
691646 }
692647 }
693648
@@ -705,6 +660,14 @@ module PatternTrees {
705660
706661 class OrPatTree extends PostOrderPatTree instanceof OrPat {
707662 override Pat getPat ( int i ) { result = OrPat .super .getPat ( i ) }
663+
664+ override predicate succ ( AstNode pred , AstNode succ , Completion c ) {
665+ // Failed patterns advance normally between children
666+ c .( MatchCompletion ) .failed ( ) and super .succ ( pred , succ , c )
667+ or
668+ // Successful pattern step to this
669+ c .( MatchCompletion ) .succeeded ( ) and succ = this and last ( this .getPat ( _) , pred , c )
670+ }
708671 }
709672
710673 class ParenPatTree extends ControlFlowTree , ParenPat {
0 commit comments