Skip to content

Commit 8703e21

Browse files
authored
Merge pull request github#17996 from owen-mc/java/lightweight-IR-layer-classes
Java: Make separate classes for different control flow node kinds
2 parents 9c0dddb + 8e11789 commit 8703e21

File tree

1 file changed

+72
-43
lines changed

1 file changed

+72
-43
lines changed

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

Lines changed: 72 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -104,31 +104,6 @@ module ControlFlow {
104104

105105
/** A node in the expression-level control-flow graph. */
106106
class Node extends TNode {
107-
/** Gets the statement containing this node, if any. */
108-
Stmt getEnclosingStmt() {
109-
result = this.asStmt() or
110-
result = this.asExpr().getEnclosingStmt()
111-
}
112-
113-
/** 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-
}
119-
120-
/** Gets the statement this `Node` corresponds to, if any. */
121-
Stmt asStmt() { this = TStmtNode(result) }
122-
123-
/** Gets the expression this `Node` corresponds to, if any. */
124-
Expr asExpr() { this = TExprNode(result) }
125-
126-
/** Gets the call this `Node` corresponds to, if any. */
127-
Call asCall() {
128-
result = this.asExpr() or
129-
result = this.asStmt()
130-
}
131-
132107
/** Gets an immediate successor of this node. */
133108
Node getASuccessor() { result = succ(this) }
134109

@@ -147,34 +122,88 @@ module ControlFlow {
147122
/** Gets the basic block that contains this node. */
148123
BasicBlock getBasicBlock() { result.getANode() = this }
149124

150-
/** 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
125+
/** Gets the statement containing this node, if any. */
126+
Stmt getEnclosingStmt() { none() }
127+
128+
/** Gets the immediately enclosing callable whose body contains this node. */
129+
Callable getEnclosingCallable() { none() }
130+
131+
/** Gets the statement this `Node` corresponds to, if any. */
132+
Stmt asStmt() { this = TStmtNode(result) }
133+
134+
/** Gets the expression this `Node` corresponds to, if any. */
135+
Expr asExpr() { this = TExprNode(result) }
136+
137+
/** Gets the call this `Node` corresponds to, if any. */
138+
Call asCall() {
139+
result = this.asExpr() or
140+
result = this.asStmt()
157141
}
158142

143+
/** Gets a textual representation of this element. */
144+
string toString() { none() }
145+
159146
/** 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-
}
147+
Location getLocation() { none() }
165148

166149
/**
167150
* Gets the most appropriate AST node for this control flow node, if any.
168151
*/
169-
ExprParent getAstNode() {
170-
result = this.asExpr() or
171-
result = this.asStmt() or
172-
this = TExitNode(result)
173-
}
152+
ExprParent getAstNode() { none() }
153+
}
154+
155+
/** A control-flow node that represents the evaluation of an expression. */
156+
class ExprNode extends Node, TExprNode {
157+
Expr e;
158+
159+
ExprNode() { this = TExprNode(e) }
160+
161+
override Stmt getEnclosingStmt() { result = e.getEnclosingStmt() }
162+
163+
override Callable getEnclosingCallable() { result = e.getEnclosingCallable() }
164+
165+
override ExprParent getAstNode() { result = e }
166+
167+
/** Gets a textual representation of this element. */
168+
override string toString() { result = e.toString() }
169+
170+
/** Gets the source location for this element. */
171+
override Location getLocation() { result = e.getLocation() }
172+
}
173+
174+
/** A control-flow node that represents a statement. */
175+
class StmtNode extends Node, TStmtNode {
176+
Stmt s;
177+
178+
StmtNode() { this = TStmtNode(s) }
179+
180+
override Stmt getEnclosingStmt() { result = s }
181+
182+
override Callable getEnclosingCallable() { result = s.getEnclosingCallable() }
183+
184+
override ExprParent getAstNode() { result = s }
185+
186+
override string toString() { result = s.toString() }
187+
188+
override Location getLocation() { result = s.getLocation() }
174189
}
175190

176191
/** A control flow node indicating the termination of a callable. */
177-
class ExitNode extends Node, TExitNode { }
192+
class ExitNode extends Node, TExitNode {
193+
Callable c;
194+
195+
ExitNode() { this = TExitNode(c) }
196+
197+
override Callable getEnclosingCallable() { result = c }
198+
199+
override ExprParent getAstNode() { result = c }
200+
201+
/** Gets a textual representation of this element. */
202+
override string toString() { result = "Exit" }
203+
204+
/** Gets the source location for this element. */
205+
override Location getLocation() { result = c.getLocation() }
206+
}
178207
}
179208

180209
class ControlFlowNode = ControlFlow::Node;

0 commit comments

Comments
 (0)