Skip to content

Commit 75e8810

Browse files
Copilotdata-douser
andcommitted
Fix tests and add query documentation files for Rust
- Update workflow-prompts tests to expect 10 languages (was 9) - Replace 'rust' with 'kotlin' as invalid language in tests since 'rust' is now a valid supported language - Add .md documentation files for all 5 Rust tool queries Agent-Logs-Url: https://github.com/advanced-security/codeql-development-mcp-server/sessions/1817d842-51f6-4414-8df3-5b40c48bc036 Co-authored-by: data-douser <70299490+data-douser@users.noreply.github.com>
1 parent 61de78b commit 75e8810

File tree

8 files changed

+18966
-147835
lines changed

8 files changed

+18966
-147835
lines changed

server/dist/codeql-development-mcp-server.js

Lines changed: 18694 additions & 147821 deletions
Large diffs are not rendered by default.

server/dist/codeql-development-mcp-server.js.map

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# CallGraphFrom for Rust
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`).
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+
19+
## Example
20+
21+
The following Rust code demonstrates outbound calls from `source_func`:
22+
23+
```rust
24+
fn helper1() {}
25+
26+
fn helper2() {
27+
helper1();
28+
}
29+
30+
fn source_func() { // Source function for analysis
31+
helper1();
32+
helper2();
33+
}
34+
```
35+
36+
Running with `sourceFunction = "source_func"` produces results showing each call site with the message pattern ``Call from `source_func`to`helper1```.
37+
38+
## Output Format
39+
40+
The query is a `@kind problem` query producing rows of:
41+
42+
- ``select call, "Call from `source` to `callee`"``
43+
44+
## References
45+
46+
- [Rust Functions](https://doc.rust-lang.org/book/ch03-03-how-functions-work.html)
47+
- [CodeQL Call Graph Analysis](https://codeql.github.com/docs/writing-codeql-queries/about-data-flow-analysis/)
48+
- [CodeQL Library for Rust](https://codeql.github.com/docs/codeql-language-guides/codeql-library-for-rust/)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# CallGraphFromTo for Rust
2+
3+
Displays calls on reachable paths from a source function to a target function, showing transitive call graph connectivity.
4+
5+
## Overview
6+
7+
This query identifies all call sites on paths that transitively connect a source function to a target function. It uses the `calls*` transitive closure to find functions reachable from the source that can also reach the target, then reports calls within those functions.
8+
9+
The query accepts both source and target function names via external predicates (`sourceFunction` and `targetFunction`).
10+
11+
## Use Cases
12+
13+
This query is primarily used for:
14+
15+
- Understanding transitive call chains between two functions
16+
- Analyzing reachability in the call graph
17+
- Identifying intermediate functions on critical paths
18+
- Security analysis of data flow through function boundaries
19+
20+
## Example
21+
22+
The following Rust code demonstrates a transitive call chain:
23+
24+
```rust
25+
fn target() {}
26+
27+
fn intermediate() {
28+
target();
29+
}
30+
31+
fn source() {
32+
intermediate();
33+
}
34+
```
35+
36+
Running with `sourceFunction = "source"` and `targetFunction = "target"` produces results showing each call site on the path with the message pattern ``Reachable call from `intermediate`to`target```.
37+
38+
## Output Format
39+
40+
The query is a `@kind problem` query producing rows of:
41+
42+
- ``select call, "Reachable call from `caller` to `callee`"``
43+
44+
## References
45+
46+
- [Rust Functions](https://doc.rust-lang.org/book/ch03-03-how-functions-work.html)
47+
- [CodeQL Call Graph Analysis](https://codeql.github.com/docs/writing-codeql-queries/about-data-flow-analysis/)
48+
- [CodeQL Library for Rust](https://codeql.github.com/docs/codeql-language-guides/codeql-library-for-rust/)
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# CallGraphTo for Rust
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 call site and the enclosing caller, which is useful for understanding how a function is used throughout the codebase.
8+
9+
The query accepts function 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 function
16+
- Understanding how a function is used across modules
17+
- Impact analysis when modifying or deprecating a function
18+
19+
## Example
20+
21+
The following Rust code demonstrates inbound calls to `target_func`:
22+
23+
```rust
24+
fn target_func() {} // Target function for analysis
25+
26+
fn caller1() {
27+
target_func();
28+
}
29+
30+
fn caller2() {
31+
target_func();
32+
}
33+
```
34+
35+
Running with `targetFunction = "target_func"` produces results showing each call site with the message pattern ``Call to `target_func`from`caller1```.
36+
37+
## Output Format
38+
39+
The query is a `@kind problem` query producing rows of:
40+
41+
- ``select call, "Call to `callee` from `caller`"``
42+
43+
## References
44+
45+
- [Rust Functions](https://doc.rust-lang.org/book/ch03-03-how-functions-work.html)
46+
- [CodeQL Call Graph Analysis](https://codeql.github.com/docs/writing-codeql-queries/about-data-flow-analysis/)
47+
- [CodeQL Library for Rust](https://codeql.github.com/docs/codeql-language-guides/codeql-library-for-rust/)
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Print AST for Rust
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 Rust source files, which is useful for understanding code structure, inspecting how the CodeQL extractor parses modules and functions, 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 Rust functions, structs, and expressions
16+
- Debugging queries that match on AST node types
17+
- Understanding parent-child relationships between items and statements
18+
- Verifying extractor behavior for ownership, borrowing, and pattern matching
19+
- IDE integration for syntax tree visualization
20+
21+
## Example
22+
23+
The following Rust code demonstrates AST structure through function declarations and control flow:
24+
25+
```rust
26+
struct Greeter {
27+
name: String,
28+
}
29+
30+
impl Greeter {
31+
fn greet(&self) {
32+
println!("Hello, {}!", self.name);
33+
}
34+
}
35+
36+
fn main() {
37+
let g = Greeter { name: "World".to_string() };
38+
g.greet();
39+
}
40+
```
41+
42+
In the resulting AST:
43+
44+
- The module contains struct and function declarations as children
45+
- Each function body contains a block expression with statement nodes
46+
- Call expressions reference their target and arguments as child nodes
47+
48+
## Output Format
49+
50+
The query produces a graph via the parameterized `PrintAst` library module:
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+
- [The Rust Reference](https://doc.rust-lang.org/reference/)
58+
- [CodeQL Abstract Syntax Trees](https://codeql.github.com/docs/writing-codeql-queries/abstract-syntax-tree/)
59+
- [CodeQL Library for Rust](https://codeql.github.com/docs/codeql-language-guides/codeql-library-for-rust/)
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Print CFG for Rust
2+
3+
Produces a representation of a file's Control Flow Graph (CFG) for specified source files.
4+
5+
## Overview
6+
7+
The Control Flow Graph models the runtime execution order of statements and expressions within functions. Nodes represent individual executable elements and edges represent possible transitions between them, including branches, loops, and exceptional control flow.
8+
9+
This query produces the CFG for specified Rust source files, which is useful for understanding execution paths, identifying dead code, and debugging data flow queries that depend on control flow ordering.
10+
11+
## Use Cases
12+
13+
This query is primarily used for:
14+
15+
- Visualizing execution paths through Rust functions
16+
- Understanding how `if`, `match`, `loop`, `while`, and `for` affect control flow
17+
- Debugging data flow queries that depend on CFG structure
18+
- Identifying unreachable code or unexpected control flow edges
19+
- Verifying CFG behavior for Rust-specific constructs like pattern matching
20+
21+
## Example
22+
23+
The following Rust code demonstrates control flow through branching and loops:
24+
25+
```rust
26+
fn example(x: i32) -> i32 {
27+
if x > 0 {
28+
return x;
29+
}
30+
31+
let mut val = x;
32+
while val < 10 {
33+
val += 1;
34+
}
35+
val
36+
}
37+
```
38+
39+
In the resulting CFG:
40+
41+
- The `if` condition creates a branch with two successors
42+
- The early `return` creates an edge to the function exit
43+
- The `while` loop creates a back-edge from the loop body to the condition
44+
45+
## Output Format
46+
47+
The query produces a graph with:
48+
49+
- `nodes`: Each CFG node with a `semmle.label` property
50+
- `edges`: Control flow transitions between nodes
51+
52+
## References
53+
54+
- [The Rust Reference - Expressions](https://doc.rust-lang.org/reference/expressions.html)
55+
- [CodeQL Control Flow Analysis](https://codeql.github.com/docs/writing-codeql-queries/about-data-flow-analysis/)
56+
- [CodeQL Library for Rust](https://codeql.github.com/docs/codeql-language-guides/codeql-library-for-rust/)

server/test/src/prompts/workflow-prompts.test.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,13 @@ describe('Workflow Prompts', () => {
8686
// SUPPORTED_LANGUAGES
8787
// -----------------------------------------------------------------------
8888
describe('SUPPORTED_LANGUAGES', () => {
89-
it('should contain the expected 9 languages', () => {
90-
expect(SUPPORTED_LANGUAGES).toHaveLength(9);
89+
it('should contain the expected 10 languages', () => {
90+
expect(SUPPORTED_LANGUAGES).toHaveLength(10);
9191
});
9292

9393
it.each([
9494
'actions', 'cpp', 'csharp', 'go', 'java',
95-
'javascript', 'python', 'ruby', 'swift',
95+
'javascript', 'python', 'ruby', 'rust', 'swift',
9696
] as const)('should include "%s"', (lang) => {
9797
expect(SUPPORTED_LANGUAGES).toContain(lang);
9898
});
@@ -162,7 +162,7 @@ describe('Workflow Prompts', () => {
162162
});
163163

164164
it('should reject invalid language', () => {
165-
const result = testDrivenDevelopmentSchema.safeParse({ language: 'rust' });
165+
const result = testDrivenDevelopmentSchema.safeParse({ language: 'kotlin' });
166166
expect(result.success).toBe(false);
167167
});
168168

@@ -1597,14 +1597,14 @@ describe('Workflow Prompts', () => {
15971597
// -----------------------------------------------------------------------
15981598
describe('formatValidationError', () => {
15991599
it('should format invalid_enum_value with available options', () => {
1600-
const result = testDrivenDevelopmentSchema.safeParse({ language: 'rust' });
1600+
const result = testDrivenDevelopmentSchema.safeParse({ language: 'kotlin' });
16011601
expect(result.success).toBe(false);
16021602
if (!result.success) {
16031603
const msg = formatValidationError('test_driven_development', result.error);
16041604
expect(msg).toContain('Invalid input');
16051605
expect(msg).toContain('test_driven_development');
16061606
expect(msg).toContain('`language`');
1607-
expect(msg).toContain('rust');
1607+
expect(msg).toContain('kotlin');
16081608
expect(msg).toContain('javascript');
16091609
expect(msg).toContain('try again');
16101610
}
@@ -1675,13 +1675,13 @@ describe('Workflow Prompts', () => {
16751675
innerHandler,
16761676
);
16771677

1678-
const result = await safe({ language: 'rust' });
1678+
const result = await safe({ language: 'kotlin' });
16791679
// Handler should NOT be called
16801680
expect(innerHandler).not.toHaveBeenCalled();
16811681
// Should return a message, not throw
16821682
expect(result.messages).toHaveLength(1);
16831683
expect(result.messages[0].content.text).toContain('Invalid input');
1684-
expect(result.messages[0].content.text).toContain('rust');
1684+
expect(result.messages[0].content.text).toContain('kotlin');
16851685
});
16861686

16871687
it('should return inline error when required fields are missing', async () => {
@@ -1941,12 +1941,12 @@ describe('Workflow Prompts', () => {
19411941
it('explain_codeql_query handler should return inline error for invalid language', async () => {
19421942
const handler = getRegisteredHandler(mockServer, 'explain_codeql_query');
19431943
const result: PromptResult = await handler({
1944-
language: 'rust',
1944+
language: 'kotlin',
19451945
queryPath: '/q.ql',
19461946
});
19471947
const text = result.messages[0].content.text;
19481948
expect(text).toContain('Invalid input');
1949-
expect(text).toContain('rust');
1949+
expect(text).toContain('kotlin');
19501950
expect(text).toContain('javascript');
19511951
});
19521952

0 commit comments

Comments
 (0)