Skip to content

Commit 2e28558

Browse files
data-douserCopilotCopilot
authored
Add .md docs for all .ql tools queries (#78) (#79)
* Add .md docs for all tools queries (#78) Add query documentation (.md) for every `server/ql/*/tools/src/*/*.ql` query across all 9 supported languages: PrintAST, PrintCFG, CallGraphFrom, and CallGraphTo. - Add `query-documentation.test.ts` to enforce that every tools query has a matching .md file - Update `server_ql_languages_tools.instructions.md` to require query docs, clarify `@kind graph` vs detection-query guidance, and scope COMPLIANT/NON_COMPLIANT annotations to detection queries only - Remove COMPLIANT/NON_COMPLIANT annotations from existing PrintCFG docs (structural queries, not detection queries) * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Nathan Randall <70299490+data-douser@users.noreply.github.com> * [UPDATE PRIMITIVE] Consistent `CallGraphFrom`/`CallGraphTo` naming in all language docs (#80) * Initial plan * Use CallGraphFrom and CallGraphTo naming consistently in all docs (no spaces) Co-authored-by: data-douser <70299490+data-douser@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: data-douser <70299490+data-douser@users.noreply.github.com> * Update server/ql/cpp/tools/src/CallGraphFrom/CallGraphFrom.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Nathan Randall <70299490+data-douser@users.noreply.github.com> --------- Signed-off-by: Nathan Randall <70299490+data-douser@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
1 parent 6db3048 commit 2e28558

File tree

36 files changed

+1371
-19
lines changed

36 files changed

+1371
-19
lines changed

.github/instructions/server_ql_languages_tools.instructions.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,13 @@ Each language directory follows a standardized structure that enables automatic
2222
- ALWAYS place query implementation files in `tools/src/<query-name>/` subdirectories.
2323
- ALWAYS place corresponding test files in `tools/test/<query-name>/` subdirectories.
2424
- ALWAYS include proper CodeQL query metadata using `@name`, `@description`, `@id`, `@kind`, and `@tags` annotations.
25+
- ALWAYS create a `.md` query documentation file alongside every `.ql` query in `tools/src/<query-name>/` (e.g., `PrintAST.md` next to `PrintAST.ql`). This is enforced by the `query-documentation.test.ts` unit test.
26+
- ALWAYS use the existing `server/ql/*/tools/src/PrintCFG/PrintCFG.md` files as the canonical style reference for `@kind graph` query documentation. These docs describe the structural output (nodes/edges) rather than flagging problems, so code examples should illustrate what structure the query visualizes — not whether code is compliant or non-compliant.
2527
- ALWAYS create `.qlref` files that reference the correct query path relative to the tools directory.
2628
- ALWAYS create `.expected` files with the expected output for each test case.
27-
- ALWAYS implement test code source files that test both the query's ability to ignore `COMPLIANT` code patterns AND to detect `NON_COMPLIANT` code patterns.
28-
- ALWAYS comment test cases as either `COMPLIANT` (i.e. query should not match) or `NON-COMPLIANT` (i.e. query should match).
29+
- ALWAYS implement test code source files that test both the query's ability to ignore `COMPLIANT` code patterns AND to detect `NON_COMPLIANT` code patterns for detection-style queries (`@kind problem` / `@kind path-problem`).
30+
- ALWAYS comment test cases as either `COMPLIANT` (i.e. query should not match) or `NON-COMPLIANT` (i.e. query should match) for detection-style queries.
31+
- ALWAYS omit `COMPLIANT` and `NON_COMPLIANT` annotations from `@kind graph` query documentation and test code, because these queries produce structural output (ASTs, CFGs, call graphs) rather than detecting problems.
2932
- ALWAYS use the `server/scripts/install-packs.sh` script to install dependencies for CodeQL packs defined under the `server/ql/*/language/tools/` directories.
3033
- ALWAYS use explicit version numbers in `codeql-pack.yml` files; never use wildcards (`*`).
3134
- ALWAYS set `ql-mcp-*` pack versions to match the CodeQL CLI version from `.codeql-version` (without the `v` prefix).
@@ -51,4 +54,5 @@ Each language directory follows a standardized structure that enables automatic
5154
- NEVER create `.qlref` files with incorrect paths or missing target queries.
5255
- NEVER mix different query purposes within a single query file.
5356
- NEVER omit required CodeQL query metadata annotations.
57+
- NEVER omit query documentation (`.md`) for any query published in a `tools/src/` pack directory.
5458
- NEVER create test cases that don't actually exercise the query logic being tested.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Print AST for GitHub Actions
2+
3+
Outputs a representation of the Abstract Syntax Tree (AST) for GitHub Actions workflows and composite actions.
4+
5+
## Overview
6+
7+
The Abstract Syntax Tree is a hierarchical representation of source code structure. Each node represents a syntactic construct (job, step, expression, etc.) and edges represent parent-child containment relationships.
8+
9+
This query produces the full AST for specified GitHub Actions YAML files, which is useful for understanding workflow structure, inspecting how the CodeQL extractor parses action definitions, and debugging query logic that operates on AST nodes.
10+
11+
## Use Cases
12+
13+
This query is primarily used for:
14+
15+
- Inspecting how CodeQL represents workflow structure
16+
- Debugging queries that match on AST node types
17+
- Understanding parent-child relationships between jobs, steps, and expressions
18+
- Verifying extractor behavior for composite actions and reusable workflows
19+
- IDE integration for syntax tree visualization
20+
21+
## Example
22+
23+
The following GitHub Actions workflow demonstrates AST structure through jobs and steps:
24+
25+
```yaml
26+
name: Example Workflow
27+
on: [push]
28+
jobs:
29+
build: # Job node in AST
30+
runs-on: ubuntu-latest
31+
steps:
32+
- uses: actions/checkout@v2 # Step node in AST
33+
- name: Build
34+
run: make build # Run step with expression
35+
```
36+
37+
In the resulting AST:
38+
39+
- The workflow root contains job definitions as children
40+
- Each job contains step nodes
41+
- `uses` and `run` steps produce distinct AST node types
42+
43+
## Output Format
44+
45+
The query produces a graph via the `PrintAstConfiguration` library:
46+
47+
- `nodes`: Each AST node with its type, label, and properties
48+
- `edges`: Parent-child relationships forming the syntax tree
49+
50+
## References
51+
52+
- [GitHub Actions Workflow Syntax](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions)
53+
- [CodeQL Abstract Syntax Trees](https://codeql.github.com/docs/writing-codeql-queries/abstract-syntax-tree/)

server/ql/actions/tools/src/PrintCFG/PrintCFG.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ The following GitHub Actions workflow demonstrates control flow through jobs and
2626
name: Example Workflow
2727
on: [push]
2828
jobs:
29-
test: # COMPLIANT - Job creates CFG node
29+
test: # Job creates CFG node
3030
runs-on: ubuntu-latest
3131
steps:
32-
- uses: actions/checkout@v2 # COMPLIANT - Step creates CFG node
33-
- name: Run tests # COMPLIANT - Steps execute sequentially
32+
- uses: actions/checkout@v2 # Step creates CFG node
33+
- name: Run tests # Steps execute sequentially
3434
run: echo "Testing"
3535
```
3636
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# CallGraphFrom for C++
2+
3+
Displays calls made from a specified function, showing the call graph outbound from the source function.
4+
5+
## Overview
6+
7+
This query identifies all function calls made within the body of a named function, producing an outbound call graph. Given a source function name, it reports each call site and the callee, which is useful for understanding function dependencies and call chains.
8+
9+
The query accepts function names via an external predicate (`sourceFunction`) and supports both simple and qualified name matching.
10+
11+
## Use Cases
12+
13+
This query is primarily used for:
14+
15+
- Mapping outbound dependencies of a specific function
16+
- Understanding what a function calls and in what order
17+
- Analyzing call chains for refactoring or security review
18+
- IDE integration for call hierarchy navigation
19+
20+
## Example
21+
22+
The following C++ code demonstrates outbound calls from `sourceFunc`:
23+
24+
```cpp
25+
void helper1() {}
26+
void helper2() { helper1(); }
27+
28+
void sourceFunc() { // Source function for analysis
29+
helper1();
30+
helper2();
31+
}
32+
```
33+
34+
Running with `sourceFunction = "sourceFunc"` produces results showing each call site with the message pattern `Call from 'sourceFunc' to 'helper1'`.
35+
## Output Format
36+
37+
The query is a `@kind problem` query producing rows of:
38+
39+
- `select call, "Call from 'source' to 'callee'"`
40+
41+
## References
42+
43+
- [C++ Functions](https://en.cppreference.com/w/cpp/language/functions)
44+
- [CodeQL Call Graph Analysis](https://codeql.github.com/docs/writing-codeql-queries/about-data-flow-analysis/)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# CallGraphTo for C++
2+
3+
Displays calls made to a specified function, showing the call graph inbound to the target function.
4+
5+
## Overview
6+
7+
This query identifies all call sites that invoke a named function, producing an inbound call graph. Given a target function name, it reports each caller and call location, which is useful for understanding how a function is used across the codebase.
8+
9+
The query accepts function names via an external predicate (`targetFunction`) and supports both simple and qualified name matching.
10+
11+
## Use Cases
12+
13+
This query is primarily used for:
14+
15+
- Finding all callers of a specific function
16+
- Impact analysis before modifying a function signature
17+
- Understanding usage patterns and entry points
18+
- IDE integration for call hierarchy navigation
19+
20+
## Example
21+
22+
The following C++ code demonstrates inbound calls to `targetFunc`:
23+
24+
```cpp
25+
void targetFunc() {} // Target function for analysis
26+
27+
void caller1() { targetFunc(); }
28+
void caller2() { targetFunc(); }
29+
```
30+
31+
Running with `targetFunction = "targetFunc"` produces results showing each call site with the message pattern `Call to 'targetFunc' from 'caller1'`.
32+
33+
## Output Format
34+
35+
The query is a `@kind problem` query producing rows of:
36+
37+
- `select call, "Call to 'target' from 'caller'"`
38+
39+
## References
40+
41+
- [C++ Functions](https://en.cppreference.com/w/cpp/language/functions)
42+
- [CodeQL Call Graph Analysis](https://codeql.github.com/docs/writing-codeql-queries/about-data-flow-analysis/)
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Print AST for C++
2+
3+
Outputs a representation of the Abstract Syntax Tree (AST) for specified source files.
4+
5+
## Overview
6+
7+
The Abstract Syntax Tree is a hierarchical representation of source code structure. Each node represents a syntactic construct (declaration, statement, expression, etc.) and edges represent parent-child containment relationships.
8+
9+
This query produces the full AST for specified C++ source files, which is useful for understanding code structure, inspecting how the CodeQL extractor parses declarations and expressions, and debugging query logic that operates on AST nodes.
10+
11+
## Use Cases
12+
13+
This query is primarily used for:
14+
15+
- Inspecting how CodeQL represents C++ declarations and expressions
16+
- Debugging queries that match on AST node types
17+
- Understanding parent-child relationships between classes, functions, and statements
18+
- Verifying extractor behavior for templates, macros, and overloaded operators
19+
- IDE integration for syntax tree visualization
20+
21+
## Example
22+
23+
The following C++ code demonstrates AST structure through declarations and statements:
24+
25+
```cpp
26+
#include <iostream>
27+
28+
class Example {
29+
public:
30+
void greet(const std::string& name) { // Function declaration in AST
31+
std::cout << "Hello, " << name << "!" << std::endl;
32+
}
33+
};
34+
35+
int main() { // Top-level declaration
36+
Example e;
37+
e.greet("World");
38+
return 0;
39+
}
40+
```
41+
42+
In the resulting AST:
43+
44+
- The class declaration contains member function declarations as children
45+
- Each function body contains a statement list
46+
- Call expressions reference their target and arguments as child nodes
47+
48+
## Output Format
49+
50+
The query produces a graph via the `PrintAstConfiguration` library:
51+
52+
- `nodes`: Each AST node with its type, label, and properties
53+
- `edges`: Parent-child relationships forming the syntax tree
54+
55+
## References
56+
57+
- [C++ Language Reference](https://en.cppreference.com/w/cpp/language)
58+
- [CodeQL Abstract Syntax Trees](https://codeql.github.com/docs/writing-codeql-queries/abstract-syntax-tree/)

server/ql/cpp/tools/src/PrintCFG/PrintCFG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ The following C++ code demonstrates control flow through conditional statements
2525
```cpp
2626
void example(int x) {
2727
int result = 0;
28-
if (x > 0) { // COMPLIANT - Branching creates CFG edges
28+
if (x > 0) { // Branching creates CFG edges
2929
result = 1;
3030
} else {
3131
result = -1;
3232
}
3333

34-
for (int i = 0; i < 3; i++) { // COMPLIANT - Loop creates cyclic CFG
34+
for (int i = 0; i < 3; i++) { // Loop creates cyclic CFG
3535
result = result + i;
3636
}
3737
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# CallGraphFrom for `csharp` Source Files
2+
3+
Displays calls made from a specified method, showing the call graph outbound from the source method.
4+
5+
## Overview
6+
7+
This query identifies all method calls made within the body of a named method, producing an outbound call graph. Given a source method name, it reports each call site and the callee, which is useful for understanding method dependencies and call chains.
8+
9+
The query accepts method names via an external predicate (`sourceFunction`).
10+
11+
## Use Cases
12+
13+
This query is primarily used for:
14+
15+
- Mapping outbound dependencies of a specific method
16+
- Understanding what a method calls and in what order
17+
- Analyzing call chains for refactoring or security review
18+
- IDE integration for call hierarchy navigation
19+
20+
## Example
21+
22+
The following C# code demonstrates outbound calls from `SourceMethod`:
23+
24+
```csharp
25+
void Helper1() {}
26+
void Helper2() { Helper1(); }
27+
28+
void SourceMethod() { // Source method for analysis
29+
Helper1();
30+
Helper2();
31+
}
32+
```
33+
34+
Running with `sourceFunction = "SourceMethod"` produces results showing each call site with the message pattern `Call from 'SourceMethod' to 'Helper1'`.
35+
36+
## Output Format
37+
38+
The query is a `@kind problem` query producing rows of:
39+
40+
- `select call, "Call from 'source' to 'callee'"`
41+
42+
## References
43+
44+
- [C# Methods](https://learn.microsoft.com/en-us/dotnet/csharp/methods)
45+
- [CodeQL Call Graph Analysis](https://codeql.github.com/docs/writing-codeql-queries/about-data-flow-analysis/)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# CallGraphTo for `csharp` Source Files
2+
3+
Displays calls made to a specified method, showing the call graph inbound to the target method.
4+
5+
## Overview
6+
7+
This query identifies all call sites that invoke a named method, producing an inbound call graph. Given a target method name, it reports each caller and call location, which is useful for understanding how a method is used across the codebase.
8+
9+
The query accepts method names via an external predicate (`targetFunction`).
10+
11+
## Use Cases
12+
13+
This query is primarily used for:
14+
15+
- Finding all callers of a specific method
16+
- Impact analysis before modifying a method signature
17+
- Understanding usage patterns and entry points
18+
- IDE integration for call hierarchy navigation
19+
20+
## Example
21+
22+
The following C# code demonstrates inbound calls to `TargetMethod`:
23+
24+
```csharp
25+
void TargetMethod() {} // Target method for analysis
26+
27+
void Caller1() { TargetMethod(); }
28+
void Caller2() { TargetMethod(); }
29+
```
30+
31+
Running with `targetFunction = "TargetMethod"` produces results showing each call site with the message pattern `Call to 'TargetMethod' from 'Caller1'`.
32+
33+
## Output Format
34+
35+
The query is a `@kind problem` query producing rows of:
36+
37+
- `select call, "Call to 'target' from 'caller'"`
38+
39+
## References
40+
41+
- [C# Methods](https://learn.microsoft.com/en-us/dotnet/csharp/methods)
42+
- [CodeQL Call Graph Analysis](https://codeql.github.com/docs/writing-codeql-queries/about-data-flow-analysis/)
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Print AST for `csharp` Source Files
2+
3+
Outputs a representation of the Abstract Syntax Tree (AST) for specified source files.
4+
5+
## Overview
6+
7+
The Abstract Syntax Tree is a hierarchical representation of source code structure. Each node represents a syntactic construct (declaration, statement, expression, etc.) and edges represent parent-child containment relationships.
8+
9+
This query produces the full AST for specified C# source files, which is useful for understanding code structure, inspecting how the CodeQL extractor parses classes and methods, and debugging query logic that operates on AST nodes.
10+
11+
## Use Cases
12+
13+
This query is primarily used for:
14+
15+
- Inspecting how CodeQL represents C# classes, methods, and expressions
16+
- Debugging queries that match on AST node types
17+
- Understanding parent-child relationships between namespaces, types, and members
18+
- Verifying extractor behavior for generics, LINQ, and async/await patterns
19+
- IDE integration for syntax tree visualization
20+
21+
## Example
22+
23+
The following C# code demonstrates AST structure through class and method declarations:
24+
25+
```csharp
26+
using System;
27+
28+
public class Example {
29+
public void Greet(string name) { // Method declaration in AST
30+
Console.WriteLine($"Hello, {name}!");
31+
}
32+
33+
public static void Main(string[] args) { // Entry point declaration
34+
var e = new Example();
35+
e.Greet("World");
36+
}
37+
}
38+
```
39+
40+
In the resulting AST:
41+
42+
- The class declaration contains method declarations as children
43+
- Each method body contains a block with statement nodes
44+
- Call expressions reference their target and arguments as child nodes
45+
46+
## Output Format
47+
48+
The query produces a graph via the `PrintAstConfiguration` library:
49+
50+
- `nodes`: Each AST node with its type, label, and properties
51+
- `edges`: Parent-child relationships forming the syntax tree
52+
53+
## References
54+
55+
- [C# Language Reference](https://learn.microsoft.com/en-us/dotnet/csharp/)
56+
- [CodeQL Abstract Syntax Trees](https://codeql.github.com/docs/writing-codeql-queries/abstract-syntax-tree/)

0 commit comments

Comments
 (0)