Skip to content

Commit 2f38835

Browse files
committed
feat: Add prompt files for AST, CFG, Dataflow, TaintTracking, and Variables
1 parent c5201bf commit 2f38835

File tree

5 files changed

+1081
-0
lines changed

5 files changed

+1081
-0
lines changed

.github/prompts/ast.prompt.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
---
2+
mode: 'agent'
3+
---
4+
5+
Given a AST class or set of classes, update and implement both the public and internal classes.
6+
7+
**Guidelines:**
8+
9+
- Always check the CodeQL TreeSitter.qll implementation first when checking the internal implementation to ensure consistency with the AST implementation.
10+
- Update the AST Node Type if necessary, following the guidelines in the "AST Nodes Types" section.
11+
- Always check and update the internal implementations of classes before updating the public classes.
12+
- Internal implementations should never return the TreeSitter class directly, always import and use `Impl` types.
13+
14+
## Read TreeSitter Implementation
15+
16+
Before implementing any AST classes or predicates, you should first read the CodeQL `TreeSitter.qll` implementation.
17+
This will help understand how the AST classes are implemented and how they relate to the TreeSitter implementation.
18+
The TreeSitter implementation is stored in the `TreeSitter.qll` file in the `ql/lib/codeql/bicep/ast/internal` directory.
19+
20+
## AST Nodes Types
21+
22+
If you are asked to update the AstNode type to include a new type, you should follow the guidelines below.
23+
24+
- Read the `AstNodes.qll` file in the `ql/lib/codeql/bicep/ast/internal` directory to understand how the AstNode type is implemented.
25+
- SuperTypes are `TExpr`, `TStmts`, `TCallable`, `TLiterals`, `TConditionals`, etc.
26+
- Add the AST Node Type (e.g. `T${AstNode}`) to the SuperType
27+
- Update the `AstNodes.qll` file to include the new type.
28+
- Ensure that the new type is consistent with the existing types in the `AstNodes.qll` file
29+
30+
**Example:**
31+
32+
```codeql
33+
class TExpr = ${AstNode1} or ${AstNode2} or ${AstNode3} or ...;
34+
```
35+
36+
## Internal Abstract Syntax Tree Implementation
37+
38+
If you are asked to implementation any internal AstNode classes or predicates, you should follow the guidelines below.
39+
Internal classes and predicates should be stored in the `ql/lib/codeql/bicep/ast/internal/${AST_NODE}.qll` directory.
40+
41+
The following rules should be followed when implementing AST classes and predicates:
42+
43+
- Internal implementations should never return the TreeSitter class directly, always import and use `Impl` types
44+
- All internal classes should extend a SuperType class which can be found in `ast/internal/${SuperType}.qll` file.
45+
- If the SuperType isn't known, check the `internal/AstNodes.qll`
46+
- Core logic should be in the internal class and reflected in the public facing class
47+
- Used named prediates the Tree Sitter class should be used in the internal implementation.
48+
- If only `getChild(i)` is avalible, look at the Tree Sitter grammar and check which possition the field is in.
49+
- Include all of the correct imports for Impl classes
50+
- Convert TreeSitter classes to CodeQL classes by using the `toTreeSitter()` method.
51+
- Example: `toTreeSitter(result) = ast.<TreeSitterPredicate>()`
52+
- Internal classes can call prediates from the `ast` by using the `toTreeSitter(result) = ast.<predicate>()` syntax.
53+
- Update internal implemention to directly use predicates from Tree Sitter module by using the ast in the class
54+
- include import statements for Impl classes, excluding the `Impl`
55+
- For example: `private import ${CLASS}`
56+
57+
**Example getting name field in the TreeSitter module:**
58+
59+
```codeql
60+
class ${AstNode}Impl extends ${AstNodeSuperType} {
61+
private Bicep::${TREESITTER_NODE} ast;
62+
63+
${ReturnType}Impl <predicate_name>() {
64+
toTreeSitter(result) = ast.get<name>()
65+
}
66+
}
67+
```
68+
69+
## Public Abstract Syntax Tree Implementation
70+
71+
The public user facing classes and predicates should be implemented in the `ql/lib/codeql/bicep/ast/${AST_NODE}.qll` directory.
72+
The public classes and predicates should follow the guidelines below:
73+
74+
- Public classes should extend a base class such as:
75+
- `Expr`: for expressions
76+
- `Literals`: literals in the language
77+
- `Stmts`: statements in the language
78+
- `Calls`: for function / method calls
79+
- `Callable`: for functions, methods, and lambdas definitions
80+
- `Conditionals`: for if, switch, and other conditional statements
81+
- Public classes should use `instanceof ${AstNode}Impl` to check if the internal implementation is used.
82+
- Implement all abstract predicates from the base class
83+
- Predicates that are defined in the internal implementation should be used in the public implementation.
84+
- Using the `${AstNode}Impl.super.${predicate}` syntax.
85+
- Example: `Type getType() { result = TypeImpl.super.getType() }
86+
- Public classes should be in the base class
87+
- Public classes should define a `getAPrimaryQlClass()` predicate that returns the primary CodeQL class name.
88+
- Public classes should define a `toString()` predicate that returns a string representation of the class.
89+
- All public classes and predicates should be documented with examples and descriptions.
90+
91+
**Example:**
92+
93+
```codeql
94+
class ${AstNode} extends Expr instanceof ${AstNode}Impl {
95+
96+
/** Returns the name of the AST node. */
97+
${ReturnType} <predicate_name>() {
98+
result = ${AstNode}Impl.super.<predicate_name>();
99+
}
100+
}
101+
```

.github/prompts/cfg.prompt.md

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
---
2+
mode: 'agent'
3+
---
4+
5+
Given a AST class or set of classes, create the various CFG related classes.
6+
This includes the following:
7+
- ControlFlowGraphImpl Tree class
8+
- CfgNodes classes for each AST Node
9+
10+
**Guidelines:**
11+
12+
- Classify the AST class into the appropriate Control Flow Graph (CFG) class.
13+
- Implement the `ControlFlowGraphImpl.qll` class if it does not exist.
14+
- Implement the `CfgNodes` classes for each AST Node, ensuring that they follow the naming conventions and structure outlined below.
15+
- All ControlFlowGraph Tree classes should be in the `ControlFlowGraphImpl.qll` file.
16+
- All CfgNodes classes should be in the `CfgNodes.qll` file.
17+
18+
## Reading AST Implementaion
19+
20+
All public AST classes are are in the `ql/lib/codeql/bicep/ast/*.qll` files.
21+
Read the classes implementation and documentation to understand the structure and relationships of the AST nodes.
22+
23+
## Classification
24+
25+
The AST classes should be classified into the following categories based on their structure and relationships:
26+
27+
- **LeafTree**:
28+
- AST nodes that do not have children, such as literals and identifiers.
29+
- **StandardPostOrderTree**:
30+
- AST nodes that are traversed in a post-order manner
31+
- **PreOrderTree**:
32+
- AST nodes that are traversed in a pre-order manner, meaning the node itself is visited before its children.
33+
- **PostOrderTree**:
34+
- AST nodes that are traversed in a post-order manner,
35+
36+
Once the classification is done, the appropriate Control Flow Graph (CFG) class should be created.
37+
38+
## Control Flow Graph Implementaion
39+
40+
If you are asked to implement any Control Flow Graph (CFG) classes or predicates, you should follow the guidelines below.
41+
The Control Flow Graph (CFG) is a representation of all paths that might be traversed through a program during its execution.
42+
The Control Flow Graph library is in `ql/lib/codeql/**/controlflow/internal/ControlFlowGraphImpl.qll`
43+
44+
An AST node can only be represented as a single Control Flow Graph node class.
45+
All Control Flow Graph node classes should have a suffix of `Tree` to indicate that they are part of the Control Flow Graph library.
46+
Example classes include `ExprTree`, `StmtsTree`, and `ProgramTree`.
47+
48+
Use the `first()` and `last()` predicates to indicate the first and last nodes in the control flow.
49+
50+
### CFG LeafTree Nodes
51+
52+
The LeafTree Nodes are a part of the Control Flow Graph library and represent an end nodes in the CFG.
53+
LeafTree Nodes are used to represent nodes in the CFG that do not have any children, meaning they are the end points of a path in the graph.
54+
55+
All Literals AST types are represented as LeafTree Nodes.
56+
57+
### CFG StandardPostOrderTree Nodes
58+
59+
The StandardPostOrderTree Nodes are a part of the Control Flow Graph library and represent the nodes in the CFG that are traversed in a post-order manner.
60+
StandardPostOrderTree Nodes are used to represent nodes in the CFG that are traversed in a post-order manner, meaning that the children of a node are visited before the node itself.
61+
62+
Expressions and statements in the CFG are represented as StandardPostOrderTree Nodes.
63+
64+
If an expression or statement uses a predicate for accessing its children it should be used.
65+
If an expression or statement does not have a predicate for accessing its children, the `getChild(i)` method should be used to access the children.
66+
67+
The following predicates should be implemented and overrided:
68+
- `override AstNode getChildNode(int i)`
69+
- to get the child node at index `i`.
70+
- result should be the child node at index `i`.
71+
- If a node has multiple nodes, add the children in the order of execution in a Bicep program
72+
73+
**StandardPostOrderTree Class Example:**
74+
75+
```codeql
76+
class ${AstNode}Tree extends StandardPostOrderTree instanceof ${AstNode} {
77+
override AstNode getChildNode(int i) {
78+
i = 0 and result = super.getAChild()
79+
}
80+
}
81+
```
82+
83+
### CFG PreOrderTree Nodes
84+
85+
The PreOrderTree Nodes are a part of the Control Flow Graph library and represent the nodes in the CFG that are traversed in a pre-order manner.
86+
PreOrderTree Nodes are used to represent nodes in the CFG that are traversed in a pre-order manner, meaning that the node itself is visited before its children.
87+
88+
The following predicates should be implemented and overrided:
89+
90+
- `final override predicate propagatesAbnormal(AstNode child)`
91+
- to indicate if the node propagates abnormal control flow to its child.
92+
- child should be matched with the child node of the AST node.
93+
- `override predicate succ(AstNode pred, AstNode succ, Completion c)`
94+
- to indicate the successor of the node.
95+
- `pred` should be the predecessor node.
96+
- `succ` should be the successor node.
97+
- `c` should be the completion of the successor node.
98+
- `override predicate last(AstNode node, Completion c)`
99+
- to indicate if the node is the last node in the control flow.
100+
- `node` should be the node to check.
101+
- `c` should be the completion of the node.
102+
103+
**PreOrderTree Class Example:**
104+
105+
```codeql
106+
class ${AstNode}Tree extends PreOrderTree instanceof ${AstNode} {
107+
final override predicate propagatesAbnormal(AstNode child) { child = super.getIdentifier() }
108+
109+
override predicate succ(AstNode pred, AstNode succ, Completion c) {
110+
// Start with the identifier
111+
pred = this and first(super.getIdentifier(), succ) and completionIsSimple(c)
112+
or
113+
last(super.getIdentifier(), pred, c) and first(super.getDefaultValue(), succ) and completionIsNormal(c)
114+
}
115+
116+
override predicate last(AstNode node, Completion c) {
117+
node = super.getDefaultValue() and completionIsNormal(c)
118+
}
119+
}
120+
```
121+
122+
Check and validate if a CFG Tree class is present in the `ControlFlowGraphImpl.qll` file.
123+
If on Tree class is not present, implement the class for the desired node.
124+
125+
## CfgNodes Implementaion
126+
127+
Check and validate if the `${AstNode}ChildMapping` or `${AstNode}CfgNode` classes are in the `CfgNodes.qll` file.
128+
Exprs and Stmts should be under there modules such as `ExprNodes` and `StmtsNodes`.
129+
All CfgNodes classes either end with `CfgNode` or `ChildMapping`.
130+
131+
For Expr based AST Nodes:
132+
- Create a `ChildMapping` abstract class inheriting both `ExprChildMapping` and `${AstNode}`
133+
- Override the `relevantChild(AstNode n)` prediate
134+
- Create a class called `${AstNode}CfgNode` which extends the `ExprCfgNode`
135+
- override `e` with the `${AstNode}ChildMapping`
136+
- implement `final override ${AstNode} getExpr() { result = super.getExpr() }
137+
138+
All Expr's with Left and Right Operations, implement final predicates returning `ExprCfgNode`

0 commit comments

Comments
 (0)