@@ -6,6 +6,14 @@ private import SuccessorType
66private newtype TCompletion =
77 TSimpleCompletion ( ) or
88 TBooleanCompletion ( Boolean b ) or
9+ TMatchCompletion ( Boolean isMatch ) or
10+ TLoopCompletion ( TLoopJumpType kind , TLabelType label ) {
11+ label = TNoLabel ( )
12+ or
13+ kind = TBreakJump ( ) and label = TLabel ( any ( BreakExpr b ) .getLifetime ( ) .getText ( ) )
14+ or
15+ kind = TContinueJump ( ) and label = TLabel ( any ( ContinueExpr b ) .getLifetime ( ) .getText ( ) )
16+ } or
917 TReturnCompletion ( )
1018
1119/** A completion of a statement or an expression. */
@@ -51,6 +59,10 @@ abstract class ConditionalCompletion extends NormalCompletion {
5159 /** Gets the Boolean value of this conditional completion. */
5260 final boolean getValue ( ) { result = value }
5361
62+ final predicate succeeded ( ) { value = true }
63+
64+ final predicate failed ( ) { value = false }
65+
5466 /** Gets the dual completion. */
5567 abstract ConditionalCompletion getDual ( ) ;
5668}
@@ -62,7 +74,34 @@ abstract class ConditionalCompletion extends NormalCompletion {
6274class BooleanCompletion extends ConditionalCompletion , TBooleanCompletion {
6375 BooleanCompletion ( ) { this = TBooleanCompletion ( value ) }
6476
65- override predicate isValidForSpecific ( AstNode e ) { e = any ( IfExpr c ) .getCondition ( ) }
77+ override predicate isValidForSpecific ( AstNode e ) {
78+ e = any ( IfExpr c ) .getCondition ( )
79+ or
80+ any ( MatchArm arm ) .getGuard ( ) = e
81+ or
82+ exists ( BinaryExpr expr |
83+ expr .getOperatorName ( ) = [ "&&" , "||" ] and
84+ e = expr .getLhs ( )
85+ )
86+ or
87+ exists ( Expr parent | this .isValidForSpecific ( parent ) |
88+ parent =
89+ any ( PrefixExpr expr |
90+ expr .getOperatorName ( ) = "!" and
91+ e = expr .getExpr ( )
92+ )
93+ or
94+ parent =
95+ any ( BinaryExpr expr |
96+ expr .getOperatorName ( ) = [ "&&" , "||" ] and
97+ e = expr .getRhs ( )
98+ )
99+ or
100+ parent = any ( IfExpr ie | e = [ ie .getThen ( ) , ie .getElse ( ) ] )
101+ or
102+ parent = any ( BlockExpr be | e = be .getStmtList ( ) .getTailExpr ( ) )
103+ )
104+ }
66105
67106 /** Gets the dual Boolean completion. */
68107 override BooleanCompletion getDual ( ) { result = TBooleanCompletion ( value .booleanNot ( ) ) }
@@ -72,6 +111,63 @@ class BooleanCompletion extends ConditionalCompletion, TBooleanCompletion {
72111 override string toString ( ) { result = "boolean(" + value + ")" }
73112}
74113
114+ /**
115+ * A completion that represents the result of a pattern match.
116+ */
117+ class MatchCompletion extends TMatchCompletion , ConditionalCompletion {
118+ MatchCompletion ( ) { this = TMatchCompletion ( value ) }
119+
120+ override predicate isValidForSpecific ( AstNode e ) { e instanceof Pat }
121+
122+ override MatchSuccessor getAMatchingSuccessorType ( ) { result .getValue ( ) = value }
123+
124+ /** Gets the dual match completion. */
125+ override MatchCompletion getDual ( ) { result = TMatchCompletion ( value .booleanNot ( ) ) }
126+
127+ override string toString ( ) { result = "match(" + value + ")" }
128+ }
129+
130+ /**
131+ * A completion that represents a break or a continue.
132+ */
133+ class LoopJumpCompletion extends TLoopCompletion , Completion {
134+ override LoopJumpSuccessor getAMatchingSuccessorType ( ) {
135+ result = TLoopSuccessor ( this .getKind ( ) , this .getLabelType ( ) )
136+ }
137+
138+ final TLoopJumpType getKind ( ) { this = TLoopCompletion ( result , _) }
139+
140+ final TLabelType getLabelType ( ) { this = TLoopCompletion ( _, result ) }
141+
142+ final predicate hasLabel ( ) { this .getLabelType ( ) = TLabel ( _) }
143+
144+ final string getLabelName ( ) { TLabel ( result ) = this .getLabelType ( ) }
145+
146+ final predicate isContinue ( ) { this .getKind ( ) = TContinueJump ( ) }
147+
148+ final predicate isBreak ( ) { this .getKind ( ) = TBreakJump ( ) }
149+
150+ override predicate isValidForSpecific ( AstNode e ) {
151+ this .isBreak ( ) and
152+ e instanceof BreakExpr and
153+ (
154+ not e .( BreakExpr ) .hasLifetime ( ) and not this .hasLabel ( )
155+ or
156+ e .( BreakExpr ) .getLifetime ( ) .getText ( ) = this .getLabelName ( )
157+ )
158+ or
159+ this .isContinue ( ) and
160+ e instanceof ContinueExpr and
161+ (
162+ not e .( ContinueExpr ) .hasLifetime ( ) and not this .hasLabel ( )
163+ or
164+ e .( ContinueExpr ) .getLifetime ( ) .getText ( ) = this .getLabelName ( )
165+ )
166+ }
167+
168+ override string toString ( ) { result = this .getAMatchingSuccessorType ( ) .toString ( ) }
169+ }
170+
75171/**
76172 * A completion that represents a return.
77173 */
0 commit comments