@@ -6,6 +6,14 @@ private import SuccessorType
6
6
private newtype TCompletion =
7
7
TSimpleCompletion ( ) or
8
8
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
9
17
TReturnCompletion ( )
10
18
11
19
/** A completion of a statement or an expression. */
@@ -51,6 +59,10 @@ abstract class ConditionalCompletion extends NormalCompletion {
51
59
/** Gets the Boolean value of this conditional completion. */
52
60
final boolean getValue ( ) { result = value }
53
61
62
+ final predicate succeeded ( ) { value = true }
63
+
64
+ final predicate failed ( ) { value = false }
65
+
54
66
/** Gets the dual completion. */
55
67
abstract ConditionalCompletion getDual ( ) ;
56
68
}
@@ -62,7 +74,34 @@ abstract class ConditionalCompletion extends NormalCompletion {
62
74
class BooleanCompletion extends ConditionalCompletion , TBooleanCompletion {
63
75
BooleanCompletion ( ) { this = TBooleanCompletion ( value ) }
64
76
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
+ }
66
105
67
106
/** Gets the dual Boolean completion. */
68
107
override BooleanCompletion getDual ( ) { result = TBooleanCompletion ( value .booleanNot ( ) ) }
@@ -72,6 +111,63 @@ class BooleanCompletion extends ConditionalCompletion, TBooleanCompletion {
72
111
override string toString ( ) { result = "boolean(" + value + ")" }
73
112
}
74
113
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
+
75
171
/**
76
172
* A completion that represents a return.
77
173
*/
0 commit comments