@@ -8,6 +8,51 @@ private import BasicBlocks
88private import ControlFlowGraph
99import internal.ControlFlowGraphImpl
1010
11+ /**
12+ * A class for mapping parent-child AST nodes to parent-child CFG nodes.
13+ */
14+ abstract private class ChildMapping extends AstNode {
15+ /**
16+ * Holds if `child` is a (possibly nested) child of this expression
17+ * for which we would like to find a matching CFG child.
18+ */
19+ abstract predicate relevantChild ( AstNode child ) ;
20+
21+ pragma [ nomagic]
22+ abstract predicate reachesBasicBlock ( AstNode child , CfgNode cfn , BasicBlock bb ) ;
23+
24+ /**
25+ * Holds if there is a control-flow path from `cfn` to `cfnChild`, where `cfn`
26+ * is a control-flow node for this expression, and `cfnChild` is a control-flow
27+ * node for `child`.
28+ *
29+ * The path never escapes the syntactic scope of this expression.
30+ */
31+ cached
32+ predicate hasCfgChild ( AstNode child , CfgNode cfn , CfgNode cfnChild ) {
33+ this .reachesBasicBlock ( child , cfn , cfnChild .getBasicBlock ( ) ) and
34+ cfnChild .getAstNode ( ) = child
35+ }
36+ }
37+
38+ /**
39+ * A class for mapping parent-child AST nodes to parent-child CFG nodes.
40+ */
41+ abstract private class ExprChildMapping extends Expr , ChildMapping {
42+ pragma [ nomagic]
43+ override predicate reachesBasicBlock ( AstNode child , CfgNode cfn , BasicBlock bb ) {
44+ this .relevantChild ( child ) and
45+ cfn = this .getAControlFlowNode ( ) and
46+ bb .getANode ( ) = cfn
47+ or
48+ exists ( BasicBlock mid |
49+ this .reachesBasicBlock ( child , cfn , mid ) and
50+ bb = mid .getAPredecessor ( ) and
51+ not mid .getANode ( ) .getAstNode ( ) = child
52+ )
53+ }
54+ }
55+
1156/** A control-flow node that wraps an AST expression. */
1257class ExprCfgNode extends AstCfgNode {
1358 string getAPrimaryQlClass ( ) { result = "ExprCfgNode" }
@@ -44,6 +89,62 @@ class LiteralsCfgNode extends AstCfgNode {
4489 Literals getLiteral ( ) { result = l }
4590}
4691
92+ class VariableCfgNode extends AstCfgNode {
93+ string getAPrimaryQlClass ( ) { result = "VariableCfgNode" }
94+
95+ Variable v ;
96+
97+ VariableCfgNode ( ) { v .getAstNode ( ) = this .getAstNode ( ) }
98+
99+ /**
100+ * Gets the underlying `Variable` expression.
101+ */
102+ Variable getExpr ( ) { result = v }
103+
104+ /** Gets the name of the variable. */
105+ string getName ( ) { result = v .getName ( ) }
106+ }
107+
108+ /** A control-flow node that wraps a `VariableAccess` AST expression. */
109+ class VariableAccessCfgNode extends AstCfgNode {
110+ string getAPrimaryQlClass ( ) { result = "VariableAccessCfgNode" }
111+
112+ VariableAccess v ;
113+
114+ VariableAccessCfgNode ( ) { v .getAstNode ( ) = this .getAstNode ( ) }
115+
116+ /**
117+ * Gets the underlying `VariableAccess` expression.
118+ */
119+ VariableAccess getExpr ( ) { result = v }
120+
121+ /** Gets the variable */
122+ VariableCfgNode getTarget ( ) { result .getExpr ( ) = v .getVariable ( ) }
123+ }
124+
125+ /** A control-flow node that wraps a `VariableReadAccess` AST expression. */
126+ class VariableReadAccessCfgNode extends VariableAccessCfgNode {
127+ override string getAPrimaryQlClass ( ) { result = "VariableReadAccessCfgNode" }
128+
129+ override VariableReadAccess v ;
130+
131+ override VariableReadAccess getExpr ( ) { result = super .getExpr ( ) }
132+
133+ Variable getVariable ( ) { result = v .getVariable ( ) }
134+ }
135+
136+ class VariableWriteAccessCfgNode extends VariableAccessCfgNode {
137+ override string getAPrimaryQlClass ( ) { result = "VariableWriteAccessCfgNode" }
138+
139+ override VariableWriteAccess v ;
140+
141+ override VariableWriteAccess getExpr ( ) { result .asExpr ( ) = v .asExpr ( ) }
142+
143+ Variable getVariable ( ) { result = v .getVariable ( ) }
144+
145+ final ExprCfgNode getReceiver ( ) { result .getExpr ( ) = v .asExpr ( ) }
146+ }
147+
47148/** Provides classes for control-flow nodes that wrap AST expressions. */
48149module ExprNodes {
49150 /** A mapping from a child of an expression to an expression. */
@@ -140,7 +241,7 @@ module ExprNodes {
140241 }
141242
142243 /** A mapping from a child of an Arguments expression to the expression. */
143- abstract class ArgumentsChildMapping extends ExprChildMapping , Arguments {
244+ abstract class ArgumentsChildMapping extends ExprNodes :: ExprChildMapping , Arguments {
144245 override predicate relevantChild ( AstNode n ) { n = this .getArgument ( _) }
145246 }
146247
@@ -154,7 +255,9 @@ module ExprNodes {
154255 }
155256
156257 /** A mapping from a child of an AssignmentExpression to the expression. */
157- abstract class AssignmentExpressionChildMapping extends ExprChildMapping , AssignmentExpression {
258+ abstract class AssignmentExpressionChildMapping extends ExprNodes:: ExprChildMapping ,
259+ AssignmentExpression
260+ {
158261 override predicate relevantChild ( AstNode n ) { n = this .getLeft ( ) or n = this .getRight ( ) }
159262 }
160263
@@ -168,7 +271,7 @@ module ExprNodes {
168271 }
169272
170273 /** A mapping from a child of a BinaryExpression to the expression. */
171- abstract class BinaryExpressionChildMapping extends ExprChildMapping , BinaryExpression {
274+ abstract class BinaryExpressionChildMapping extends ExprNodes :: ExprChildMapping , BinaryExpression {
172275 override predicate relevantChild ( AstNode n ) { n = this .getLeft ( ) or n = this .getRight ( ) }
173276 }
174277
@@ -194,7 +297,7 @@ module ExprNodes {
194297 }
195298
196299 /** A mapping from a child of an Interpolation to the expression. */
197- abstract class InterpolationChildMapping extends ExprChildMapping , Interpolation {
300+ abstract class InterpolationChildMapping extends ExprNodes :: ExprChildMapping , Interpolation {
198301 override predicate relevantChild ( AstNode n ) { n = this .getExpression ( ) }
199302 }
200303
@@ -306,10 +409,177 @@ module ExprNodes {
306409
307410 override UnaryExpression getExpr ( ) { result = super .getExpr ( ) }
308411 }
412+
413+ /** A mapping from a child of a Parameter to the expression. */
414+ abstract class ParameterChildMapping extends ExprNodes:: ExprChildMapping , Parameter {
415+ override predicate relevantChild ( AstNode n ) { n = this .getIdentifier ( ) or n = this .getType ( ) }
416+ }
417+
418+ /** A control-flow node that wraps a Parameter AST node. */
419+ class ParameterCfgNode extends ExprCfgNode {
420+ override string getAPrimaryQlClass ( ) { result = "ParameterCfgNode" }
421+
422+ override Parameter e ;
423+
424+ override Parameter getExpr ( ) { result = super .getExpr ( ) }
425+ }
426+
427+ /** A mapping from a child of Parameters to the expression. */
428+ abstract class ParametersChildMaping extends ExprNodes:: ExprChildMapping , Parameters {
429+ override predicate relevantChild ( AstNode n ) { n = this .getParameter ( _) }
430+ }
431+
432+ /** A control-flow node that wraps a Parameters AST node. */
433+ class ParametersCfgNode extends ExprCfgNode {
434+ override string getAPrimaryQlClass ( ) { result = "ParametersCfgNode" }
435+
436+ override Parameters e ;
437+
438+ override Parameters getExpr ( ) { result = super .getExpr ( ) }
439+ }
309440}
310441
442+ /** Provides classes for control-flow nodes that wrap AST statements. */
311443module StmtNodes {
312- /** A control-flow node that wraps a `Cmd` AST expression. */
444+ /** A mapping from a child of a statement to a statement. */
445+ abstract class StmtChildMapping extends Stmts {
446+ /** Holds if `n` is a relevant child of this statement. */
447+ abstract predicate relevantChild ( AstNode n ) ;
448+ }
449+
450+ /** A control-flow node that wraps an AssertStatement AST node. */
451+ class AssertStatementCfgNode extends StmtsCfgNode {
452+ override string getAPrimaryQlClass ( ) { result = "AssertStatementCfgNode" }
453+
454+ override AssertStatementStmt s ;
455+
456+ override AssertStatementStmt getStmt ( ) { result = super .getStmt ( ) }
457+ }
458+
459+ /** A control-flow node that wraps a ForStatement AST node. */
460+ class ForStatementCfgNode extends StmtsCfgNode {
461+ override string getAPrimaryQlClass ( ) { result = "ForStatementCfgNode" }
462+
463+ override ForStatementStmt s ;
464+
465+ override ForStatementStmt getStmt ( ) { result = super .getStmt ( ) }
466+ }
467+
468+ /** A mapping from a child of an IfStatement to the statement. */
469+ abstract class IfStatementChildMapping extends StmtChildMapping , IfStatement {
470+ override predicate relevantChild ( AstNode n ) { n = this .getCondition ( ) or n = this .getBody ( ) }
471+ }
472+
473+ /** A control-flow node that wraps an IfStatement AST node. */
474+ class IfStatementCfgNode extends StmtsCfgNode {
475+ override string getAPrimaryQlClass ( ) { result = "IfStatementCfgNode" }
476+
477+ override IfStatement s ;
478+
479+ override IfStatement getStmt ( ) { result = super .getStmt ( ) }
480+
481+ /** Gets the condition CFG node */
482+ final ExprCfgNode getCondition ( ) {
483+ result = this .getAPredecessor ( ) .( ExprCfgNode ) and
484+ result .getExpr ( ) = this .getStmt ( ) .getCondition ( )
485+ }
486+
487+ /** Gets the body CFG node */
488+ final ExprCfgNode getBody ( ) {
489+ result = this .getAPredecessor ( ) .( ExprCfgNode ) and
490+ result .getExpr ( ) = this .getStmt ( ) .getBody ( )
491+ }
492+ }
493+
494+ /** A control-flow node that wraps an ImportStatement AST node. */
495+ class ImportStatementCfgNode extends StmtsCfgNode {
496+ override string getAPrimaryQlClass ( ) { result = "ImportStatementCfgNode" }
497+
498+ override ImportStatementStmt s ;
499+
500+ override ImportStatementStmt getStmt ( ) { result = super .getStmt ( ) }
501+ }
502+
503+ /** A control-flow node that wraps an Infrastructure AST node. */
504+ class InfrastructureCfgNode extends AstCfgNode {
505+ string getAPrimaryQlClass ( ) { result = "InfrastructureCfgNode" }
506+
507+ Infrastructure i ;
508+
509+ InfrastructureCfgNode ( ) { i = this .getAstNode ( ) }
510+
511+ /** Gets the underlying Infrastructure. */
512+ Infrastructure getInfrastructure ( ) { result = i }
513+ }
514+
515+ /** A mapping from a child of a ParameterDeclaration to the statement. */
516+ abstract class ParameterDeclarationChildMapping extends StmtChildMapping , ParameterDeclaration {
517+ override predicate relevantChild ( AstNode n ) {
518+ n = this .getIdentifier ( ) or n = this .getDefaultValue ( )
519+ }
520+ }
521+
522+ /** A control-flow node that wraps a ParameterDeclaration AST node. */
523+ class ParameterDeclarationCfgNode extends StmtsCfgNode {
524+ override string getAPrimaryQlClass ( ) { result = "ParameterDeclarationCfgNode" }
525+
526+ override ParameterDeclaration s ;
527+
528+ override ParameterDeclaration getStmt ( ) { result = super .getStmt ( ) }
529+ }
530+
531+ /** A mapping from a child of an OutputDeclaration to the statement. */
532+ abstract class OutputDeclarationChildMapping extends StmtChildMapping , OutputDeclaration {
533+ override predicate relevantChild ( AstNode n ) { n = this .getIdentifier ( ) or n = this .getValue ( ) }
534+ }
535+
536+ /** A control-flow node that wraps an OutputDeclaration AST node. */
537+ class OutputDeclarationCfgNode extends StmtsCfgNode {
538+ override string getAPrimaryQlClass ( ) { result = "OutputDeclarationCfgNode" }
539+
540+ override OutputDeclaration s ;
541+
542+ override OutputDeclaration getStmt ( ) { result = super .getStmt ( ) }
543+ }
544+
545+ /** A mapping from a child of a UserDefinedFunction to the statement. */
546+ abstract class UserDefinedFunctionChildMapping extends StmtChildMapping , UserDefinedFunction {
547+ override predicate relevantChild ( AstNode n ) {
548+ n = this .getIdentifier ( ) or
549+ n = this .getDeclaredParameters ( ) or
550+ n = this .getReturnType ( ) or
551+ n = this .getBody ( )
552+ }
553+ }
554+
555+ /** A control-flow node that wraps a UserDefinedFunction AST node. */
556+ class UserDefinedFunctionCfgNode extends StmtsCfgNode {
557+ override string getAPrimaryQlClass ( ) { result = "UserDefinedFunctionCfgNode" }
558+
559+ override UserDefinedFunction s ;
560+
561+ override UserDefinedFunction getStmt ( ) { result = super .getStmt ( ) }
562+ }
563+
564+ /** A control-flow node that wraps an ImportWithStatement AST node. */
565+ class ImportWithStatementCfgNode extends StmtsCfgNode {
566+ override string getAPrimaryQlClass ( ) { result = "ImportWithStatementCfgNode" }
567+
568+ override ImportWithStatementStmt s ;
569+
570+ override ImportWithStatementStmt getStmt ( ) { result = super .getStmt ( ) }
571+ }
572+
573+ /** A control-flow node that wraps a UsingStatement AST node. */
574+ class UsingStatementCfgNode extends StmtsCfgNode {
575+ override string getAPrimaryQlClass ( ) { result = "UsingStatementCfgNode" }
576+
577+ override UsingStatementStmt s ;
578+
579+ override UsingStatementStmt getStmt ( ) { result = super .getStmt ( ) }
580+ }
581+
582+ /** A control-flow node that wraps a UserDefinedFunction AST node. */
313583 class CallCfgNode extends StmtsCfgNode {
314584 override string getAPrimaryQlClass ( ) { result = "CallCfgNode" }
315585
0 commit comments