Skip to content

Commit d2348b5

Browse files
committed
Make separate classes for control flow node kinds
This puts all the logic of a particular control flow node kind into one place and makes it easier to add new kinds.
1 parent 52f58ec commit d2348b5

File tree

1 file changed

+65
-33
lines changed

1 file changed

+65
-33
lines changed

java/ql/lib/semmle/code/java/ControlFlowGraph.qll

Lines changed: 65 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -105,29 +105,19 @@ module ControlFlow {
105105
/** A node in the expression-level control-flow graph. */
106106
class Node extends TNode {
107107
/** Gets the statement containing this node, if any. */
108-
Stmt getEnclosingStmt() {
109-
result = this.asStmt() or
110-
result = this.asExpr().getEnclosingStmt()
111-
}
108+
Stmt getEnclosingStmt() { none() }
112109

113110
/** Gets the immediately enclosing callable whose body contains this node. */
114-
Callable getEnclosingCallable() {
115-
this = TExitNode(result) or
116-
result = this.asStmt().getEnclosingCallable() or
117-
result = this.asExpr().getEnclosingCallable()
118-
}
111+
Callable getEnclosingCallable() { none() }
119112

120113
/** Gets the statement this `Node` corresponds to, if any. */
121-
Stmt asStmt() { this = TStmtNode(result) }
114+
Stmt asStmt() { none() }
122115

123116
/** Gets the expression this `Node` corresponds to, if any. */
124-
Expr asExpr() { this = TExprNode(result) }
117+
Expr asExpr() { none() }
125118

126119
/** Gets the call this `Node` corresponds to, if any. */
127-
Call asCall() {
128-
result = this.asExpr() or
129-
result = this.asStmt()
130-
}
120+
Call asCall() { none() }
131121

132122
/** Gets an immediate successor of this node. */
133123
Node getASuccessor() { result = succ(this) }
@@ -148,36 +138,78 @@ module ControlFlow {
148138
BasicBlock getBasicBlock() { result.getANode() = this }
149139

150140
/** Gets a textual representation of this element. */
151-
string toString() {
152-
result = this.asExpr().toString()
153-
or
154-
result = this.asStmt().toString()
155-
or
156-
result = "Exit" and this instanceof ExitNode
157-
}
141+
string toString() { none() }
158142

159143
/** Gets the source location for this element. */
160-
Location getLocation() {
161-
result = this.asExpr().getLocation() or
162-
result = this.asStmt().getLocation() or
163-
result = this.(ExitNode).getEnclosingCallable().getLocation()
164-
}
144+
Location getLocation() { none() }
165145

166146
/**
167147
* Get the most appropriate AST node for this control flow node, if any.
168148
*
169149
* This is needed for the equivalence relation on basic blocks in range
170150
* analysis.
171151
*/
172-
ExprParent getAstNode() {
173-
result = this.asExpr() or
174-
result = this.asStmt() or
175-
this = TExitNode(result)
176-
}
152+
ExprParent getAstNode() { none() }
153+
}
154+
155+
class ExprNode extends Node, TExprNode {
156+
Expr e;
157+
158+
ExprNode() { this = TExprNode(e) }
159+
160+
override Stmt getEnclosingStmt() { result = e.getEnclosingStmt() }
161+
162+
override Callable getEnclosingCallable() { result = e.getEnclosingCallable() }
163+
164+
override Expr asExpr() { result = e }
165+
166+
override Call asCall() { result = e }
167+
168+
override ExprParent getAstNode() { result = e }
169+
170+
/** Gets a textual representation of this element. */
171+
override string toString() { result = e.toString() }
172+
173+
/** Gets the source location for this element. */
174+
override Location getLocation() { result = e.getLocation() }
175+
}
176+
177+
class StmtNode extends Node, TStmtNode {
178+
Stmt s;
179+
180+
StmtNode() { this = TStmtNode(s) }
181+
182+
override Stmt getEnclosingStmt() { result = s }
183+
184+
override Callable getEnclosingCallable() { result = s.getEnclosingCallable() }
185+
186+
override Stmt asStmt() { result = s }
187+
188+
override Call asCall() { result = s }
189+
190+
override ExprParent getAstNode() { result = s }
191+
192+
override string toString() { result = s.toString() }
193+
194+
override Location getLocation() { result = s.getLocation() }
177195
}
178196

179197
/** A synthetic node for the exit of a callable. */
180-
class ExitNode extends Node, TExitNode { }
198+
class ExitNode extends Node, TExitNode {
199+
Callable c;
200+
201+
ExitNode() { this = TExitNode(c) }
202+
203+
override Callable getEnclosingCallable() { result = c }
204+
205+
override ExprParent getAstNode() { result = c }
206+
207+
/** Gets a textual representation of this element. */
208+
override string toString() { result = "Exit" }
209+
210+
/** Gets the source location for this element. */
211+
override Location getLocation() { result = c.getLocation() }
212+
}
181213
}
182214

183215
class ControlFlowNode = ControlFlow::Node;

0 commit comments

Comments
 (0)