11/**
22 * Bicep variable declarations.
33 */
4+
45private import bicep
56private import AstNodes
7+ private import Calls
68private import Idents
79private import Stmts
810private import codeql.bicep.controlflow.BasicBlocks as BasicBlocks
@@ -14,13 +16,198 @@ private import internal.VariableDeclaration
1416 * A VariableDeclaration unknown AST node.
1517 */
1618class VariableDeclaration extends AstNode instanceof VariableDeclarationImpl {
17- /**
18- * Gets the identifier of the variable declaration.
19- */
20- Idents getIdentifier ( ) { result = VariableDeclarationImpl .super .getIdentifier ( ) }
21-
22- /**
23- * Gets the initializer expression of the variable declaration.
24- */
25- Expr getInitializer ( ) { result = VariableDeclarationImpl .super .getInitializer ( ) }
19+ /**
20+ * Gets the identifier of the variable declaration.
21+ */
22+ Idents getIdentifier ( ) { result = VariableDeclarationImpl .super .getIdentifier ( ) }
23+
24+ /**
25+ * Gets the initializer expression of the variable declaration.
26+ */
27+ Expr getInitializer ( ) { result = VariableDeclarationImpl .super .getInitializer ( ) }
28+ }
29+
30+ private predicate variableDecl ( AstNode node , string name ) {
31+ exists ( ParameterDeclaration param |
32+ param .getName ( ) = name and
33+ node = param
34+ )
35+ or
36+ exists ( VariableDeclaration vardelc |
37+ vardelc .getIdentifier ( ) .getName ( ) = name and
38+ node = vardelc
39+ )
40+ or
41+ exists ( OutputDeclaration output |
42+ output .getIdentifier ( ) .getName ( ) = name and
43+ node = output
44+ )
45+ }
46+
47+ /**
48+ * Variable represents a variable defination.
49+ */
50+ class Variable extends MkVariable {
51+ private AstNode node ;
52+ private string name ;
53+
54+ Variable ( ) { this = MkVariable ( node , name ) }
55+
56+ string getName ( ) { result = name }
57+
58+ string toString ( ) { result = "Variable[" + name + "]" }
59+
60+ AstNode getAstNode ( ) { result = node }
61+
62+ /**
63+ * Get the location of this variable.
64+ */
65+ Location getLocation ( ) { result = node .getLocation ( ) }
66+
67+ /**
68+ * Geta the inner variable of this variable.
69+ */
70+ VariableAccess getAnAccess ( ) { result .getVariable ( ) = this }
71+
72+ /**
73+ * Gets the type of this variable, if any.
74+ */
75+ Type getType ( ) {
76+ result = this .getParameter ( ) .getType ( )
77+ or
78+ result = this .getOutput ( ) .getType ( )
79+ }
80+
81+ /**
82+ * Gets the parameter of this variable, if any.
83+ */
84+ ParameterDeclaration getParameter ( ) {
85+ exists ( ParameterDeclaration param |
86+ param .getName ( ) = this .getName ( ) and
87+ param .getEnclosingCfgScope ( ) = this .getEnclosingCfgScope ( ) and
88+ result = param
89+ )
90+ }
91+
92+ /**
93+ * Gets the variable declaration of this variable, if any.
94+ */
95+ OutputDeclaration getOutput ( ) {
96+ exists ( OutputDeclaration output |
97+ output .getIdentifier ( ) .getName ( ) = this .getName ( ) and
98+ output .getEnclosingCfgScope ( ) = this .getEnclosingCfgScope ( ) and
99+ result = output
100+ )
101+ }
102+
103+ /**
104+ * Gets the enclosing scope of this variable, if any.
105+ */
106+ CfgScope getEnclosingCfgScope ( ) { result = node .getEnclosingCfgScope ( ) }
107+
108+ // Expr getInitializer() { }
109+ string getAPrimaryQlClass ( ) { result = "Variable" }
110+ }
111+
112+ private predicate access ( AstNode node , Variable v , string name ) {
113+ exists ( Identifier ident |
114+ ident .getName ( ) = name and
115+ // Make sure they are not in a declare statement
116+ not ident .getParent ( ) instanceof VariableDeclaration and
117+ // not ident.getParent() instanceof ParameterDeclaration and
118+ // not ident.getParent() instanceof OutputDeclaration and
119+ // Make sure they are in the same scope
120+ ident .getName ( ) = v .getName ( ) and
121+ ident .getEnclosingCfgScope ( ) = v .getEnclosingCfgScope ( ) and
122+ ident = node
123+ )
124+ }
125+
126+ /**
127+ * VariableAccess is a class that represents the access to a variable.
128+ */
129+ class VariableAccess extends MkVariableAccess , TVariableAccess {
130+ private string name ;
131+ private AstNode node ;
132+ private Variable v ;
133+
134+ VariableAccess ( ) { this = MkVariableAccess ( node , v , name ) }
135+
136+ string getName ( ) { result = name }
137+
138+ AstNode getAstNode ( ) { result = node }
139+
140+ Variable getVariable ( ) { result = v }
141+
142+ string toString ( ) { result = "VariableAccess[" + name + "]" }
143+
144+ /**
145+ * Get the location of this variable.
146+ */
147+ Location getLocation ( ) { result = node .getLocation ( ) }
148+
149+ /**
150+ * Gets the type of this variable, if any.
151+ */
152+ Type getType ( ) { result = this .getVariable ( ) .getType ( ) }
153+
154+ /**
155+ * Gets the enclosing scope of this variable, if any.
156+ */
157+ CfgScope getEnclosingCfgScope ( ) { result = v .getEnclosingCfgScope ( ) }
158+
159+ string getAPrimaryQlClass ( ) { result = "VariableAccess" }
26160}
161+
162+ class VariableWriteAccess extends VariableAccess {
163+ VariableWriteAccess ( ) {
164+ // Parameter
165+ this .getAstNode ( ) .getParent ( ) instanceof ParameterDeclaration
166+ or
167+ // SET
168+ this .getAstNode ( ) .getParent ( ) instanceof VariableDeclaration
169+ or
170+ // Output
171+ this .getAstNode ( ) .getParent ( ) instanceof OutputDeclaration
172+ }
173+
174+ override string getAPrimaryQlClass ( ) { result = "VariableWrite" }
175+ }
176+
177+ class VariableReadAccess extends VariableAccess {
178+ VariableReadAccess ( ) { not this instanceof VariableWriteAccess }
179+
180+ override string getAPrimaryQlClass ( ) { result = "VariableRead" }
181+ }
182+
183+ /**
184+ * Holds if the variable is written too.
185+ */
186+ // private predicate variableWrite(Variable node) {
187+ // exists(Parameter param |
188+ // param.getName() = node.getName() and
189+ // param.getEnclosingCfgScope() = node.getEnclosingCfgScope()
190+ // )
191+ // }
192+ cached
193+ private module Cached {
194+ cached
195+ newtype TVariable =
196+ TResource ( Resource resource , string name ) { resource .getName ( ) = name } or
197+ TVariableDecl ( VariableDeclaration varDecl , string name ) {
198+ varDecl .getIdentifier ( ) .getName ( ) = name
199+ } or
200+ TParameter ( ParameterDeclaration param , string name ) { param .getName ( ) = name } or
201+ TOutput ( OutputDeclaration output , string name ) { output .getIdentifier ( ) .getName ( ) = name } or
202+ MkVariable ( AstNode definingNode , string name ) { variableDecl ( definingNode , name ) }
203+
204+ cached
205+ newtype TVariableAccess =
206+ TIdent ( Identifier ident , string name ) { ident .getName ( ) = name } or
207+ MkVariableAccess ( AstNode node , Variable v , string name ) { variableAccess ( node , v , name ) }
208+
209+ cached
210+ predicate variableAccess ( AstNode node , Variable v , string name ) { access ( node , v , name ) }
211+ }
212+
213+ private import Cached
0 commit comments