@@ -7,7 +7,7 @@ module ControlFlow {
7
7
private import semmle.code.csharp.controlflow.BasicBlocks as BBs
8
8
import semmle.code.csharp.controlflow.internal.SuccessorType
9
9
private import SuccessorTypes
10
- private import internal.ControlFlowGraphImpl
10
+ private import internal.ControlFlowGraphImpl as Impl
11
11
private import internal.Splitting as Splitting
12
12
13
13
/**
@@ -25,18 +25,16 @@ module ControlFlow {
25
25
* Only nodes that can be reached from the callable entry point are included in
26
26
* the CFG.
27
27
*/
28
- class Node extends TCfgNode {
29
- /** Gets a textual representation of this control flow node. */
30
- string toString ( ) { none ( ) }
31
-
28
+ class Node extends Impl:: Node {
32
29
/** Gets the control flow element that this node corresponds to, if any. */
33
- ControlFlowElement getElement ( ) { none ( ) }
34
-
35
- /** Gets the location of this control flow node. */
36
- Location getLocation ( ) { result = this .getElement ( ) .getLocation ( ) }
30
+ final ControlFlowElement getAstNode ( ) { result = super .getAstNode ( ) }
37
31
38
- /** Holds if this control flow node has conditional successors. */
39
- predicate isCondition ( ) { exists ( this .getASuccessorByType ( any ( ConditionalSuccessor e ) ) ) }
32
+ /**
33
+ * DEPRECATED: Use `getAstNode` instead.
34
+ *
35
+ * Gets the control flow element that this node corresponds to, if any.
36
+ */
37
+ deprecated ControlFlowElement getElement ( ) { result = this .getAstNode ( ) }
40
38
41
39
/** Gets the basic block that this control flow node belongs to. */
42
40
BasicBlock getBasicBlock ( ) { result .getANode ( ) = this }
@@ -183,7 +181,7 @@ module ControlFlow {
183
181
}
184
182
185
183
/** Gets a successor node of a given type, if any. */
186
- Node getASuccessorByType ( SuccessorType t ) { result = getASuccessor ( this , t ) }
184
+ Node getASuccessorByType ( SuccessorType t ) { result = this . getASuccessor ( t ) }
187
185
188
186
/** Gets an immediate successor, if any. */
189
187
Node getASuccessor ( ) { result = this .getASuccessorByType ( _) }
@@ -234,80 +232,39 @@ module ControlFlow {
234
232
result = this .getASuccessorByType ( any ( BooleanSuccessor t | t .getValue ( ) = false ) )
235
233
}
236
234
237
- /** Holds if this node has more than one predecessor. */
238
- predicate isJoin ( ) { strictcount ( this .getAPredecessor ( ) ) > 1 }
239
-
240
- /** Holds if this node has more than one successor. */
241
- predicate isBranch ( ) { strictcount ( this .getASuccessor ( ) ) > 1 }
242
-
243
235
/** Gets the enclosing callable of this control flow node. */
244
- final Callable getEnclosingCallable ( ) { result = getNodeCfgScope ( this ) }
236
+ final Callable getEnclosingCallable ( ) { result = Impl :: getNodeCfgScope ( this ) }
245
237
}
246
238
247
239
/** Provides different types of control flow nodes. */
248
240
module Nodes {
249
241
/** A node for a callable entry point. */
250
- class EntryNode extends Node , TEntryNode {
242
+ class EntryNode extends Node instanceof Impl :: EntryNode {
251
243
/** Gets the callable that this entry applies to. */
252
- Callable getCallable ( ) { this = TEntryNode ( result ) }
244
+ Callable getCallable ( ) { result = this . getScope ( ) }
253
245
254
246
override BasicBlocks:: EntryBlock getBasicBlock ( ) { result = Node .super .getBasicBlock ( ) }
255
-
256
- private Assignable getAssignable ( ) { this = TEntryNode ( result ) }
257
-
258
- override Location getLocation ( ) {
259
- result in [ this .getCallable ( ) .getLocation ( ) , this .getAssignable ( ) .getLocation ( ) ]
260
- }
261
-
262
- override string toString ( ) {
263
- result = "enter " + [ this .getCallable ( ) .toString ( ) , this .getAssignable ( ) .toString ( ) ]
264
- }
265
247
}
266
248
267
249
/** A node for a callable exit point, annotated with the type of exit. */
268
- class AnnotatedExitNode extends Node , TAnnotatedExitNode {
269
- private CfgScope scope ;
270
- private boolean normal ;
271
-
272
- AnnotatedExitNode ( ) { this = TAnnotatedExitNode ( scope , normal ) }
250
+ class AnnotatedExitNode extends Node instanceof Impl:: AnnotatedExitNode {
251
+ /** Holds if this node represent a normal exit. */
252
+ final predicate isNormal ( ) { super .isNormal ( ) }
273
253
274
254
/** Gets the callable that this exit applies to. */
275
- CfgScope getCallable ( ) { result = scope }
276
-
277
- /** Holds if this node represents a normal exit. */
278
- predicate isNormal ( ) { normal = true }
255
+ Callable getCallable ( ) { result = this .getScope ( ) }
279
256
280
257
override BasicBlocks:: AnnotatedExitBlock getBasicBlock ( ) {
281
258
result = Node .super .getBasicBlock ( )
282
259
}
283
-
284
- override Location getLocation ( ) { result = scope .getLocation ( ) }
285
-
286
- override string toString ( ) {
287
- exists ( string s |
288
- normal = true and s = "normal"
289
- or
290
- normal = false and s = "abnormal"
291
- |
292
- result = "exit " + scope + " (" + s + ")"
293
- )
294
- }
295
260
}
296
261
297
262
/** A node for a callable exit point. */
298
- class ExitNode extends Node , TExitNode {
299
- private CfgScope scope ;
300
-
301
- ExitNode ( ) { this = TExitNode ( scope ) }
302
-
263
+ class ExitNode extends Node instanceof Impl:: ExitNode {
303
264
/** Gets the callable that this exit applies to. */
304
- Callable getCallable ( ) { result = scope }
265
+ Callable getCallable ( ) { result = this . getScope ( ) }
305
266
306
267
override BasicBlocks:: ExitBlock getBasicBlock ( ) { result = Node .super .getBasicBlock ( ) }
307
-
308
- override Location getLocation ( ) { result = scope .getLocation ( ) }
309
-
310
- override string toString ( ) { result = "exit " + scope }
311
268
}
312
269
313
270
/**
@@ -317,35 +274,19 @@ module ControlFlow {
317
274
* the element is in unreachable (dead) code, and multiple when there are
318
275
* different splits for the element.
319
276
*/
320
- class ElementNode extends Node , TElementNode {
321
- private Splits splits ;
322
- private ControlFlowElement cfe ;
323
-
324
- ElementNode ( ) { this = TElementNode ( _, cfe , splits ) }
325
-
326
- override ControlFlowElement getElement ( ) { result = cfe }
327
-
328
- override string toString ( ) {
329
- result = "[" + this .getSplitsString ( ) + "] " + cfe .toString ( )
330
- or
331
- not exists ( this .getSplitsString ( ) ) and result = cfe .toString ( )
332
- }
333
-
277
+ class ElementNode extends Node instanceof Impl:: AstCfgNode {
334
278
/** Gets a comma-separated list of strings for each split in this node, if any. */
335
- string getSplitsString ( ) {
336
- result = splits .toString ( ) and
337
- result != ""
338
- }
279
+ final string getSplitsString ( ) { result = super .getSplitsString ( ) }
339
280
340
281
/** Gets a split for this control flow node, if any. */
341
- Split getASplit ( ) { result = splits .getASplit ( ) }
282
+ final Split getASplit ( ) { result = super .getASplit ( ) }
342
283
}
343
284
344
285
/** A control-flow node for an expression. */
345
286
class ExprNode extends ElementNode {
346
287
Expr e ;
347
288
348
- ExprNode ( ) { e = unique( Expr e_ | e_ = this .getElement ( ) | e_ ) }
289
+ ExprNode ( ) { e = unique( Expr e_ | e_ = this .getAstNode ( ) | e_ ) }
349
290
350
291
/** Gets the expression that this control-flow node belongs to. */
351
292
Expr getExpr ( ) { result = e }
0 commit comments