1+ // generated by { {generator} }, do not edit
2+ /**
3+ * This module provides generated wrappers around the `CfgNode` type.
4+ *
5+ * INTERNAL: Do not import directly.
6+ */
7+
8+ private import codeql.util.Location
9+ private import codeql.util.Unit
10+ private import { {include_file_import} }
11+
12+ /** Provides the input to `MakeCfgNodes` */
13+ signature module InputSig<LocationSig Loc > {
14+ class CfgNode {
15+ AstNode getAstNode();
16+
17+ string toString();
18+
19+ Loc getLocation();
20+ }
21+
22+ AstNode getDesugared(AstNode n);
23+
24+ predicate normalEvaluation(AstNode n);
25+ }
26+
27+ /**
28+ * Given a `CfgNode` implementation, provides the module `Nodes` that
29+ * contains wrappers around `CfgNode` for relevant classes.
30+ */
31+ module MakeCfgNodes<LocationSig Loc, InputSig <Loc > Input> {
32+ private import Input
33+
34+ final private class AstNodeFinal = AstNode;
35+
36+ final private class CfgNodeFinal = CfgNode;
37+
38+ /**
39+ * INTERNAL: Do not expose.
40+ */
41+ abstract class AstNodeWithChild extends AstNodeFinal {
42+ /**
43+ * Holds if `child` is a (possibly nested) child of this AST node
44+ * for which we would like to find a matching CFG child.
45+ */
46+ abstract predicate relevantChild(AstNode child);
47+ }
48+
49+ /**
50+ * INTERNAL: Do not expose.
51+ */
52+ abstract class ChildMapping extends Unit {
53+ /**
54+ * Holds if `child` is a (possibly nested) child of AST node `parent`
55+ * for which we would like to find a matching CFG child.
56+ */
57+ final predicate relevantChild(AstNode parent, AstNode child) {
58+ parent.(AstNodeWithChild).relevantChild(child)
59+ }
60+
61+ /**
62+ * Holds if there is a control-flow path from `cfn` to `cfnChild`, where `cfn`
63+ * is a control-flow node for this AST node, and `cfnChild` is a control-flow
64+ * node for `child`.
65+ *
66+ * This predicate should be implemented at the place where `MakeCfgNodes` is
67+ * invoked.
68+ */
69+ cached
70+ abstract predicate hasCfgChild(AstNode parent, AstNode child, CfgNode cfn, CfgNode cfnChild);
71+ }
72+
73+ /** Provides sub classes of `CfgNode`. */
74+ module Nodes {
75+ {{#classes} }
76+ private final class { {name} }WithChild extends AstNodeWithChild, { {name} } {
77+ override predicate relevantChild(AstNode child) {
78+ none()
79+ {{#properties} }
80+ { {#cfg} }
81+ or
82+ child = this.{ {getter} }({ {#is_indexed} }_{ {/is_indexed} })
83+ { {/cfg} }
84+ { {/properties} }
85+ }
86+ }
87+
88+ /**
89+ { {#doc} }
90+ * { {.} }
91+ { {/doc} }
92+ */
93+ final class { {name} }CfgNode extends CfgNodeFinal{ {#bases} }, { {.} }CfgNode{ {/bases} } {
94+ private {{name} } node;
95+
96+ { {name} }CfgNode() {
97+ node = this.getAstNode()
98+ }
99+
100+ /** Gets the underlying `{ {name} }`. */
101+ { {name} } get{ {name} }() { result = node }
102+
103+ { {#properties} }
104+ /**
105+ * { {> ql_property_doc} } *
106+ { {#description} }
107+ * { {.} }
108+ { {/description} }
109+ { {#internal} }
110+ * INTERNAL: Do not use.
111+ { {/internal} }
112+ */
113+ { {type} }{ {#cfg} }CfgNode{ {/cfg} } { {getter} }({ {#is_indexed} }int index{ {/is_indexed} }) {
114+ {{#cfg} }
115+ any(ChildMapping mapping).hasCfgChild(node, node.{ {getter} }({ {#is_indexed} }index{ {/is_indexed} }), this, result)
116+ { {/cfg} }
117+ { {^cfg} }
118+ { {^is_predicate} }result = { {/is_predicate} }node.{ {getter} }({ {#is_indexed} }index{ {/is_indexed} })
119+ { {/cfg} }
120+ }
121+
122+ { {#is_optional} }
123+ /**
124+ * Holds if `{ {getter} }({ {#is_repeated} }index{ {/is_repeated} })` exists.
125+ { {#internal} }
126+ * INTERNAL: Do not use.
127+ { {/internal} }
128+ */
129+ predicate has{ {singular} }({ {#is_repeated} }int index{ {/is_repeated} }) {
130+ exists(this.{{getter} }({ {#is_repeated} }index{ {/is_repeated} }))
131+ }
132+ { {/is_optional} }
133+ { {#is_indexed} }
134+
135+ /**
136+ * Gets any of the { {doc_plural} }.
137+ { {#internal} }
138+ * INTERNAL: Do not use.
139+ { {/internal} }
140+ */
141+ { {type} }{ {#cfg} }CfgNode{ {/cfg} } { {indefinite_getter} }() {
142+ result = this.{{getter} }(_)
143+ }
144+ { {^is_optional} }
145+
146+ /**
147+ * Gets the number of { {doc_plural} }.
148+ { {#internal} }
149+ * INTERNAL: Do not use.
150+ { {/internal} }
151+ */
152+ int getNumberOf{ {plural} }() {
153+ result = count(int i | exists(this.{{getter} }(i)))
154+ }
155+ { {/is_optional} }
156+ { {/is_indexed} }
157+ { {#is_unordered} }
158+ /**
159+ * Gets the number of { {doc_plural} }.
160+ { {#internal} }
161+ * INTERNAL: Do not use.
162+ { {/internal} }
163+ */
164+ int getNumberOf{ {plural} }() {
165+ result = count(this.{{getter} }())
166+ }
167+ { {/is_unordered} }
168+ { {/properties} }
169+ }
170+ { {/classes} }
171+ }
172+
173+ module Consistency {
174+ query predicate missingCfgChild(CfgNode parent, string pred, int child) {
175+ none()
176+ {{#classes} }
177+ { {#properties} }
178+ { {#cfg} }
179+ or
180+ pred = "{ {getter} }" and
181+ parent = any(Nodes::{ {name} }CfgNode cfgNode, { {name} } astNode, { {type} } res |
182+ astNode = cfgNode.get{ {name} }() and
183+ res = getDesugared(astNode.{ {getter} }({ {#is_indexed} }child{ {/is_indexed} }))
184+ { {^is_indexed} }and child = -1{ {/is_indexed} } and
185+ normalEvaluation(res) and
186+ not res = cfgNode.{ {getter} }({ {#is_indexed} }child{ {/is_indexed} }).getAstNode()
187+ |
188+ cfgNode
189+ )
190+ { {/cfg} }
191+ { {/properties} }
192+ { {/classes} }
193+ }
194+ }
195+ }
0 commit comments