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