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