@@ -290,7 +290,7 @@ module Expressions {
290290 private class SimpleNoNodeExpr extends NoNodeExpr {
291291 SimpleNoNodeExpr ( ) {
292292 this instanceof TypeAccess and
293- not this = any ( PatternMatch pm ) . getPattern ( )
293+ not this instanceof TypeAccessPatternExpr
294294 }
295295 }
296296
@@ -371,7 +371,10 @@ module Expressions {
371371 not this instanceof ConstructorInitializer and
372372 not this instanceof NotPatternExpr and
373373 not this instanceof OrPatternExpr and
374- not this instanceof AndPatternExpr
374+ not this instanceof AndPatternExpr and
375+ not this instanceof RecursivePatternExpr and
376+ not this instanceof PositionalPatternExpr and
377+ not this instanceof PropertyPatternExpr
375378 }
376379
377380 final override ControlFlowElement getChildElement ( int i ) { result = getExprChild ( this , i ) }
@@ -965,6 +968,117 @@ module Expressions {
965968 }
966969}
967970
971+ private class RecursivePatternExprTree extends PostOrderTree , RecursivePatternExpr {
972+ private Expr getTypeExpr ( ) {
973+ result = this .getVariableDeclExpr ( )
974+ or
975+ not exists ( this .getVariableDeclExpr ( ) ) and
976+ result = this .getTypeAccess ( )
977+ }
978+
979+ private PatternExpr getChildPattern ( ) {
980+ result = this .getPositionalPatterns ( )
981+ or
982+ result = this .getPropertyPatterns ( )
983+ }
984+
985+ final override predicate propagatesAbnormal ( ControlFlowElement child ) {
986+ child = this .getChildPattern ( )
987+ }
988+
989+ final override predicate first ( ControlFlowElement first ) {
990+ first ( this .getTypeExpr ( ) , first )
991+ or
992+ not exists ( this .getTypeExpr ( ) ) and
993+ first ( this .getChildPattern ( ) , first )
994+ }
995+
996+ final override predicate succ ( ControlFlowElement pred , ControlFlowElement succ , Completion c ) {
997+ // Flow from type test to child pattern
998+ last ( this .getTypeExpr ( ) , pred , c ) and
999+ first ( this .getChildPattern ( ) , succ ) and
1000+ c .( MatchingCompletion ) .getValue ( ) = true
1001+ or
1002+ // Flow from type test to self
1003+ last ( this .getTypeExpr ( ) , pred , c ) and
1004+ succ = this and
1005+ c .( MatchingCompletion ) .getValue ( ) = false
1006+ or
1007+ // Flow from child pattern to self
1008+ last ( this .getChildPattern ( ) , pred , c ) and
1009+ succ = this and
1010+ c instanceof MatchingCompletion
1011+ }
1012+ }
1013+
1014+ private class PositionalPatternExprTree extends PreOrderTree , PositionalPatternExpr {
1015+ final override predicate propagatesAbnormal ( ControlFlowElement child ) {
1016+ child = this .getPattern ( _)
1017+ }
1018+
1019+ final override predicate last ( ControlFlowElement last , Completion c ) {
1020+ last = this and
1021+ c .( MatchingCompletion ) .getValue ( ) = false
1022+ or
1023+ last ( this .getPattern ( _) , last , c ) and
1024+ c .( MatchingCompletion ) .getValue ( ) = false
1025+ or
1026+ exists ( int lst |
1027+ last ( this .getPattern ( lst ) , last , c ) and
1028+ not exists ( this .getPattern ( lst + 1 ) )
1029+ )
1030+ }
1031+
1032+ final override predicate succ ( ControlFlowElement pred , ControlFlowElement succ , Completion c ) {
1033+ // Flow from self to first pattern
1034+ pred = this and
1035+ c .( MatchingCompletion ) .getValue ( ) = true and
1036+ first ( this .getPattern ( 0 ) , succ )
1037+ or
1038+ // Flow from one pattern to the next
1039+ exists ( int i |
1040+ last ( this .getPattern ( i ) , pred , c ) and
1041+ c .( MatchingCompletion ) .getValue ( ) = true and
1042+ first ( this .getPattern ( i + 1 ) , succ )
1043+ )
1044+ }
1045+ }
1046+
1047+ private class PropertyPatternExprExprTree extends PostOrderTree , PropertyPatternExpr {
1048+ final override predicate propagatesAbnormal ( ControlFlowElement child ) {
1049+ child = this .getPattern ( _)
1050+ }
1051+
1052+ final override predicate first ( ControlFlowElement first ) {
1053+ first ( this .getPattern ( 0 ) , first )
1054+ or
1055+ not exists ( this .getPattern ( 0 ) ) and
1056+ first = this
1057+ }
1058+
1059+ final override predicate succ ( ControlFlowElement pred , ControlFlowElement succ , Completion c ) {
1060+ // Flow from one pattern to the next
1061+ exists ( int i |
1062+ last ( this .getPattern ( i ) , pred , c ) and
1063+ c .( MatchingCompletion ) .getValue ( ) = true and
1064+ first ( this .getPattern ( i + 1 ) , succ )
1065+ )
1066+ or
1067+ // Post-order: flow from last element of failing pattern to element itself
1068+ last ( this .getPattern ( _) , pred , c ) and
1069+ c .( MatchingCompletion ) .getValue ( ) = false and
1070+ succ = this
1071+ or
1072+ // Post-order: flow from last element of last pattern to element itself
1073+ exists ( int last |
1074+ last ( this .getPattern ( last ) , pred , c ) and
1075+ not exists ( this .getPattern ( last + 1 ) ) and
1076+ c instanceof MatchingCompletion and
1077+ succ = this
1078+ )
1079+ }
1080+ }
1081+
9681082module Statements {
9691083 private class StandardStmt extends StandardElement , PreOrderTree , Stmt {
9701084 StandardStmt ( ) {
0 commit comments