Skip to content

Commit a264da2

Browse files
Copilotaschackmull
andauthored
Add shared AstSig consistency checks module
Agent-Logs-Url: https://github.com/github/codeql/sessions/bf1d9f01-0696-4099-b5c6-3a13d639c3a4 Co-authored-by: aschackmull <28296824+aschackmull@users.noreply.github.com>
1 parent b027ac3 commit a264da2

1 file changed

Lines changed: 168 additions & 0 deletions

File tree

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/**
2+
* Provides consistency queries for `AstSig`.
3+
*/
4+
overlay[local?]
5+
module;
6+
7+
private import ControlFlowGraph
8+
9+
module MakeAstConsistency<LocationSig Location, AstSig<Location> Ast> {
10+
private import Ast
11+
12+
private predicate parentStep(AstNode child, AstNode parent) { child = getChild(parent, _) }
13+
14+
private predicate astMemberChild(AstNode parent, AstNode child, string member) {
15+
callableGetBody(parent.(Callable)) = child and member = "callableGetBody"
16+
or
17+
callableGetParameter(parent.(Callable), _) = child and member = "callableGetParameter"
18+
or
19+
parent.(Parameter).getDefaultValue() = child and member = "Parameter.getDefaultValue"
20+
or
21+
parent.(BlockStmt).getStmt(_) = child and member = "BlockStmt.getStmt"
22+
or
23+
parent.(BlockStmt).getLastStmt() = child and member = "BlockStmt.getLastStmt"
24+
or
25+
parent.(ExprStmt).getExpr() = child and member = "ExprStmt.getExpr"
26+
or
27+
parent.(IfStmt).getCondition() = child and member = "IfStmt.getCondition"
28+
or
29+
parent.(IfStmt).getThen() = child and member = "IfStmt.getThen"
30+
or
31+
parent.(IfStmt).getElse() = child and member = "IfStmt.getElse"
32+
or
33+
parent.(LoopStmt).getBody() = child and member = "LoopStmt.getBody"
34+
or
35+
parent.(WhileStmt).getCondition() = child and member = "WhileStmt.getCondition"
36+
or
37+
parent.(DoStmt).getCondition() = child and member = "DoStmt.getCondition"
38+
or
39+
parent.(ForStmt).getInit(_) = child and member = "ForStmt.getInit"
40+
or
41+
parent.(ForStmt).getCondition() = child and member = "ForStmt.getCondition"
42+
or
43+
parent.(ForStmt).getUpdate(_) = child and member = "ForStmt.getUpdate"
44+
or
45+
parent.(ForeachStmt).getVariable() = child and member = "ForeachStmt.getVariable"
46+
or
47+
parent.(ForeachStmt).getCollection() = child and member = "ForeachStmt.getCollection"
48+
or
49+
parent.(ReturnStmt).getExpr() = child and member = "ReturnStmt.getExpr"
50+
or
51+
parent.(Throw).getExpr() = child and member = "Throw.getExpr"
52+
or
53+
parent.(TryStmt).getBody() = child and member = "TryStmt.getBody"
54+
or
55+
parent.(TryStmt).getCatch(_) = child and member = "TryStmt.getCatch"
56+
or
57+
parent.(TryStmt).getFinally() = child and member = "TryStmt.getFinally"
58+
or
59+
getTryInit(parent.(TryStmt), _) = child and member = "getTryInit"
60+
or
61+
getTryElse(parent.(TryStmt)) = child and member = "getTryElse"
62+
or
63+
parent.(CatchClause).getVariable() = child and member = "CatchClause.getVariable"
64+
or
65+
parent.(CatchClause).getCondition() = child and member = "CatchClause.getCondition"
66+
or
67+
parent.(CatchClause).getBody() = child and member = "CatchClause.getBody"
68+
or
69+
parent.(Switch).getExpr() = child and member = "Switch.getExpr"
70+
or
71+
parent.(Switch).getCase(_) = child and member = "Switch.getCase"
72+
or
73+
parent.(Switch).getStmt(_) = child and member = "Switch.getStmt"
74+
or
75+
parent.(Case).getAPattern() = child and member = "Case.getAPattern"
76+
or
77+
parent.(Case).getGuard() = child and member = "Case.getGuard"
78+
or
79+
parent.(Case).getBody() = child and member = "Case.getBody"
80+
or
81+
parent.(ConditionalExpr).getCondition() = child and member = "ConditionalExpr.getCondition"
82+
or
83+
parent.(ConditionalExpr).getThen() = child and member = "ConditionalExpr.getThen"
84+
or
85+
parent.(ConditionalExpr).getElse() = child and member = "ConditionalExpr.getElse"
86+
or
87+
parent.(BinaryExpr).getLeftOperand() = child and member = "BinaryExpr.getLeftOperand"
88+
or
89+
parent.(BinaryExpr).getRightOperand() = child and member = "BinaryExpr.getRightOperand"
90+
or
91+
parent.(UnaryExpr).getOperand() = child and member = "UnaryExpr.getOperand"
92+
or
93+
parent.(PatternMatchExpr).getExpr() = child and member = "PatternMatchExpr.getExpr"
94+
or
95+
parent.(PatternMatchExpr).getPattern() = child and member = "PatternMatchExpr.getPattern"
96+
}
97+
98+
private class StructuredAstNode extends AstNode {
99+
StructuredAstNode() {
100+
this instanceof Callable or
101+
this instanceof Parameter or
102+
this instanceof BlockStmt or
103+
this instanceof ExprStmt or
104+
this instanceof IfStmt or
105+
this instanceof LoopStmt or
106+
this instanceof WhileStmt or
107+
this instanceof DoStmt or
108+
this instanceof ForStmt or
109+
this instanceof ForeachStmt or
110+
this instanceof ReturnStmt or
111+
this instanceof Throw or
112+
this instanceof TryStmt or
113+
this instanceof CatchClause or
114+
this instanceof Switch or
115+
this instanceof Case or
116+
this instanceof ConditionalExpr or
117+
this instanceof BinaryExpr or
118+
this instanceof UnaryExpr or
119+
this instanceof PatternMatchExpr
120+
}
121+
}
122+
123+
module Consistency {
124+
/** Holds if `child` has multiple AST parents. */
125+
query predicate multipleParents(AstNode child, AstNode parent1, AstNode parent2) {
126+
getChild(parent1, _) = child and
127+
getChild(parent2, _) = child and
128+
parent1 != parent2
129+
}
130+
131+
/**
132+
* Holds if `node` has an enclosing callable that is not reachable through
133+
* parent steps.
134+
*/
135+
query predicate nonAncestorEnclosingCallable(AstNode node, Callable callable) {
136+
callable = getEnclosingCallable(node) and
137+
not parentStep*(node, callable)
138+
}
139+
140+
/** Holds if `child` is assigned multiple child indices under `parent`. */
141+
query predicate childAtMultipleIndices(AstNode parent, AstNode child, int index1, int index2) {
142+
getChild(parent, index1) = child and
143+
getChild(parent, index2) = child and
144+
index1 < index2
145+
}
146+
147+
/** Holds if multiple children of `parent` share the same child index. */
148+
query predicate siblingsWithIdenticalIndex(
149+
AstNode parent, int index, AstNode child1, AstNode child2
150+
) {
151+
getChild(parent, index) = child1 and
152+
getChild(parent, index) = child2 and
153+
child1 != child2
154+
}
155+
156+
/** Holds if a member child relation is not reflected by `getChild`. */
157+
query predicate memberChildMissingFromGetChild(AstNode parent, AstNode child, string member) {
158+
astMemberChild(parent, child, member) and
159+
not getChild(parent, _) = child
160+
}
161+
162+
/** Holds if a `getChild` relation for a structured AST node has no matching member predicate. */
163+
query predicate getChildMissingFromMember(StructuredAstNode parent, int index, AstNode child) {
164+
child = getChild(parent, index) and
165+
not astMemberChild(parent, child, _)
166+
}
167+
}
168+
}

0 commit comments

Comments
 (0)