Skip to content

Commit 79f4f78

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 f097168 commit 79f4f78

File tree

1 file changed

+67
-33
lines changed

1 file changed

+67
-33
lines changed

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

Lines changed: 67 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,33 +138,77 @@ 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
* Gets the most appropriate AST node for this control flow node, if any.
168148
*/
169-
ExprParent getAstNode() {
170-
result = this.asExpr() or
171-
result = this.asStmt() or
172-
this = TExitNode(result)
173-
}
149+
ExprParent getAstNode() { none() }
150+
}
151+
152+
/** A control-flow node that represents the evaluation of an expression. */
153+
class ExprNode extends Node, TExprNode {
154+
Expr e;
155+
156+
ExprNode() { this = TExprNode(e) }
157+
158+
override Stmt getEnclosingStmt() { result = e.getEnclosingStmt() }
159+
160+
override Callable getEnclosingCallable() { result = e.getEnclosingCallable() }
161+
162+
override Expr asExpr() { result = e }
163+
164+
override Call asCall() { result = e }
165+
166+
override ExprParent getAstNode() { result = e }
167+
168+
/** Gets a textual representation of this element. */
169+
override string toString() { result = e.toString() }
170+
171+
/** Gets the source location for this element. */
172+
override Location getLocation() { result = e.getLocation() }
173+
}
174+
175+
/** A control-flow node that represents a statement. */
176+
class StmtNode extends Node, TStmtNode {
177+
Stmt s;
178+
179+
StmtNode() { this = TStmtNode(s) }
180+
181+
override Stmt getEnclosingStmt() { result = s }
182+
183+
override Callable getEnclosingCallable() { result = s.getEnclosingCallable() }
184+
185+
override Stmt asStmt() { result = s }
186+
187+
override Call asCall() { result = s }
188+
189+
override ExprParent getAstNode() { result = s }
190+
191+
override string toString() { result = s.toString() }
192+
193+
override Location getLocation() { result = s.getLocation() }
174194
}
175195

176196
/** A control flow node indicating the termination of a callable. */
177-
class ExitNode extends Node, TExitNode { }
197+
class ExitNode extends Node, TExitNode {
198+
Callable c;
199+
200+
ExitNode() { this = TExitNode(c) }
201+
202+
override Callable getEnclosingCallable() { result = c }
203+
204+
override ExprParent getAstNode() { result = c }
205+
206+
/** Gets a textual representation of this element. */
207+
override string toString() { result = "Exit" }
208+
209+
/** Gets the source location for this element. */
210+
override Location getLocation() { result = c.getLocation() }
211+
}
178212
}
179213

180214
class ControlFlowNode = ControlFlow::Node;

0 commit comments

Comments
 (0)