codeql-development-mcp-server 2.25.1 → 2.25.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeql-development-mcp-server",
3
- "version": "2.25.1",
3
+ "version": "2.25.2",
4
4
  "description": "An MCP server supporting LLM requests for CodeQL development tools and resources.",
5
5
  "main": "dist/codeql-development-mcp-server.js",
6
6
  "type": "module",
@@ -18,6 +18,7 @@
18
18
  "ql/javascript/tools/src/",
19
19
  "ql/python/tools/src/",
20
20
  "ql/ruby/tools/src/",
21
+ "ql/rust/tools/src/",
21
22
  "ql/swift/tools/src/",
22
23
  "scripts/setup-packs.sh",
23
24
  "package.json",
@@ -40,7 +41,7 @@
40
41
  "typescript"
41
42
  ],
42
43
  "author": "@github/ps-codeql",
43
- "license": "SEE LICENSE IN LICENSE",
44
+ "license": "LicenseRef-CodeQL-Terms",
44
45
  "repository": {
45
46
  "type": "git",
46
47
  "url": "git+https://github.com/advanced-security/codeql-development-mcp-server.git",
@@ -55,13 +56,13 @@
55
56
  "npm": ">=11.6.2"
56
57
  },
57
58
  "dependencies": {
58
- "@modelcontextprotocol/sdk": "^1.28.0",
59
- "adm-zip": "^0.5.16",
59
+ "@modelcontextprotocol/sdk": "^1.29.0",
60
+ "adm-zip": "^0.5.17",
60
61
  "cors": "^2.8.6",
61
- "dotenv": "^17.3.1",
62
+ "dotenv": "^17.4.0",
62
63
  "express": "^5.2.1",
63
64
  "js-yaml": "^4.1.1",
64
- "lowdb": "^7.0.1",
65
+ "sql.js": "^1.14.1",
65
66
  "zod": "^3.25.76"
66
67
  },
67
68
  "devDependencies": {
@@ -70,16 +71,16 @@
70
71
  "@types/cors": "^2.8.19",
71
72
  "@types/express": "^5.0.6",
72
73
  "@types/js-yaml": "^4.0.9",
73
- "@types/node": "^25.5.0",
74
- "@vitest/coverage-v8": "^4.1.2",
75
- "esbuild": "^0.27.4",
76
- "eslint": "^10.1.0",
74
+ "@types/node": "^25.6.0",
75
+ "@vitest/coverage-v8": "^4.1.4",
76
+ "esbuild": "^0.28.0",
77
+ "eslint": "^10.2.0",
77
78
  "eslint-config-prettier": "^10.1.8",
78
79
  "eslint-plugin-prettier": "^5.5.5",
79
- "prettier": "^3.8.1",
80
- "typescript": "^5.9.3",
81
- "typescript-eslint": "^8.57.2",
82
- "vitest": "^4.1.2"
80
+ "prettier": "^3.8.2",
81
+ "typescript": "^6.0.2",
82
+ "typescript-eslint": "^8.58.1",
83
+ "vitest": "^4.1.4"
83
84
  },
84
85
  "scripts": {
85
86
  "build": "npm run clean && npm run lint && npm run bundle",
package/ql/README.md CHANGED
@@ -35,6 +35,7 @@ Currently supported languages:
35
35
  - `javascript/` - JavaScript/TypeScript
36
36
  - `python/` - Python
37
37
  - `ruby/` - Ruby
38
+ - `rust/` - Rust
38
39
  - `swift/` - Swift
39
40
 
40
41
  ## Testing
@@ -1,5 +1,5 @@
1
1
  name: advanced-security/ql-mcp-actions-tools-src
2
- version: 2.25.1
2
+ version: 2.25.2
3
3
  description: 'Queries for codeql-development-mcp-server tools for actions language'
4
4
  library: false
5
5
  dependencies:
@@ -1,5 +1,5 @@
1
1
  name: advanced-security/ql-mcp-cpp-tools-src
2
- version: 2.25.1
2
+ version: 2.25.2
3
3
  description: 'Queries for codeql-development-mcp-server tools for cpp language'
4
4
  library: false
5
5
  dependencies:
@@ -1,5 +1,5 @@
1
1
  name: advanced-security/ql-mcp-csharp-tools-src
2
- version: 2.25.1
2
+ version: 2.25.2
3
3
  description: 'Queries for codeql-development-mcp-server tools for csharp language'
4
4
  library: false
5
5
  dependencies:
@@ -1,5 +1,5 @@
1
1
  name: advanced-security/ql-mcp-go-tools-src
2
- version: 2.25.1
2
+ version: 2.25.2
3
3
  description: 'Queries for codeql-development-mcp-server tools for go language'
4
4
  library: false
5
5
  dependencies:
@@ -1,5 +1,5 @@
1
1
  name: advanced-security/ql-mcp-java-tools-src
2
- version: 2.25.1
2
+ version: 2.25.2
3
3
  description: 'Queries for codeql-development-mcp-server tools for java language'
4
4
  library: false
5
5
  dependencies:
@@ -1,5 +1,5 @@
1
1
  name: advanced-security/ql-mcp-javascript-tools-src
2
- version: 2.25.1
2
+ version: 2.25.2
3
3
  description: 'Queries for codeql-development-mcp-server tools for javascript language'
4
4
  library: false
5
5
  dependencies:
@@ -1,5 +1,5 @@
1
1
  name: advanced-security/ql-mcp-python-tools-src
2
- version: 2.25.1
2
+ version: 2.25.2
3
3
  description: 'Queries for codeql-development-mcp-server tools for python language'
4
4
  library: false
5
5
  dependencies:
@@ -1,5 +1,5 @@
1
1
  name: advanced-security/ql-mcp-ruby-tools-src
2
- version: 2.25.1
2
+ version: 2.25.2
3
3
  description: 'Queries for codeql-development-mcp-server tools for ruby language'
4
4
  library: false
5
5
  dependencies:
@@ -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/)
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @name Call Graph From for rust
3
+ * @description Displays calls made from a specified function, showing the call graph outbound from the source function.
4
+ * @id rust/tools/call-graph-from
5
+ * @kind problem
6
+ * @problem.severity recommendation
7
+ * @tags call-graph
8
+ */
9
+
10
+ import rust
11
+ import ExternalPredicates
12
+
13
+ /**
14
+ * Gets a single source function name from the comma-separated list.
15
+ */
16
+ string getSourceFunctionName() {
17
+ exists(string s | sourceFunction(s) | result = s.splitAt(",").trim())
18
+ }
19
+
20
+ /**
21
+ * Gets a function by matching against the selected source function names.
22
+ */
23
+ Function getSourceFunction() { result.getName().getText() = getSourceFunctionName() }
24
+
25
+ /**
26
+ * Gets the name of the called function.
27
+ */
28
+ string getCalleeName(CallExpr call) {
29
+ if exists(call.getResolvedTarget().(Function).getName())
30
+ then result = call.getResolvedTarget().(Function).getName().getText()
31
+ else result = call.toString()
32
+ }
33
+
34
+ from CallExpr call, Function source
35
+ where
36
+ call.getEnclosingCallable() = source and
37
+ source = getSourceFunction()
38
+ select call, "Call from `" + source.getName().getText() + "` to `" + getCalleeName(call) + "`"
@@ -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/)
@@ -0,0 +1,69 @@
1
+ /**
2
+ * @name Call Graph From To for rust
3
+ * @description Displays calls on reachable paths from a source function to a target function, showing transitive call graph connectivity.
4
+ * @id rust/tools/call-graph-from-to
5
+ * @kind problem
6
+ * @problem.severity recommendation
7
+ * @tags call-graph
8
+ */
9
+
10
+ import rust
11
+ import ExternalPredicates
12
+
13
+ /**
14
+ * Gets a single source function name from the comma-separated list.
15
+ */
16
+ string getSourceFunctionName() {
17
+ exists(string s | sourceFunction(s) | result = s.splitAt(",").trim())
18
+ }
19
+
20
+ /**
21
+ * Gets a single target function name from the comma-separated list.
22
+ */
23
+ string getTargetFunctionName() {
24
+ exists(string s | targetFunction(s) | result = s.splitAt(",").trim())
25
+ }
26
+
27
+ /**
28
+ * Gets a function by matching against the selected source function names.
29
+ */
30
+ Function getSourceFunction() { result.getName().getText() = getSourceFunctionName() }
31
+
32
+ /**
33
+ * Gets a function by matching against the selected target function names.
34
+ */
35
+ Function getTargetFunction() { result.getName().getText() = getTargetFunctionName() }
36
+
37
+ /**
38
+ * Holds if function `caller` directly calls function `callee`.
39
+ */
40
+ predicate calls(Function caller_, Function callee_) {
41
+ exists(CallExpr c |
42
+ c.getEnclosingCallable() = caller_ and
43
+ c.getResolvedTarget().(Function) = callee_
44
+ )
45
+ }
46
+
47
+ /**
48
+ * Gets the name of the called function.
49
+ */
50
+ string getCalleeName(CallExpr call) {
51
+ if exists(call.getResolvedTarget().(Function).getName())
52
+ then result = call.getResolvedTarget().(Function).getName().getText()
53
+ else result = call.toString()
54
+ }
55
+
56
+ from CallExpr call, Function caller
57
+ where
58
+ call.getEnclosingCallable() = caller and
59
+ exists(Function source, Function target |
60
+ source = getSourceFunction() and
61
+ target = getTargetFunction() and
62
+ calls*(source, caller) and
63
+ exists(Function callee |
64
+ call.getResolvedTarget().(Function) = callee and
65
+ calls*(callee, target)
66
+ )
67
+ )
68
+ select call,
69
+ "Reachable call from `" + caller.getName().getText() + "` to `" + getCalleeName(call) + "`"
@@ -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/)
@@ -0,0 +1,47 @@
1
+ /**
2
+ * @name Call Graph To for rust
3
+ * @description Displays calls made to a specified function, showing the call graph inbound to the target function.
4
+ * @id rust/tools/call-graph-to
5
+ * @kind problem
6
+ * @problem.severity recommendation
7
+ * @tags call-graph
8
+ */
9
+
10
+ import rust
11
+ import ExternalPredicates
12
+
13
+ /**
14
+ * Gets a single target function name from the comma-separated list.
15
+ */
16
+ string getTargetFunctionName() {
17
+ exists(string s | targetFunction(s) | result = s.splitAt(",").trim())
18
+ }
19
+
20
+ /**
21
+ * Gets a function by matching against the selected target function names.
22
+ */
23
+ Function getTargetFunction() { result.getName().getText() = getTargetFunctionName() }
24
+
25
+ /**
26
+ * Gets the caller name for a call expression.
27
+ */
28
+ string getCallerName(CallExpr call) {
29
+ if exists(call.getEnclosingCallable().(Function).getName())
30
+ then result = call.getEnclosingCallable().(Function).getName().getText()
31
+ else result = "Top-level"
32
+ }
33
+
34
+ /**
35
+ * Gets the name of the called function.
36
+ */
37
+ string getCalleeName(CallExpr call) {
38
+ if exists(call.getResolvedTarget().(Function).getName())
39
+ then result = call.getResolvedTarget().(Function).getName().getText()
40
+ else result = call.toString()
41
+ }
42
+
43
+ from CallExpr call, Function target
44
+ where
45
+ target = getTargetFunction() and
46
+ call.getResolvedTarget() = target
47
+ select call, "Call to `" + getCalleeName(call) + "` from `" + getCallerName(call) + "`"
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Shared extensible predicate declarations for MCP server tools queries.
3
+ * Values are provided via dataExtensions YAML files during testing,
4
+ * or via a temporary data extension pack at runtime from the MCP server.
5
+ */
6
+
7
+ /** Holds for each source function name for call graph analysis. */
8
+ extensible predicate sourceFunction(string name);
9
+
10
+ /** Holds for each target function name for call graph analysis. */
11
+ extensible predicate targetFunction(string name);
12
+
13
+ /** Holds for each selected source file path for AST/CFG printing. */
14
+ extensible predicate selectedSourceFiles(string path);
@@ -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/)
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @name Print AST for rust
3
+ * @description Outputs a representation of the Abstract Syntax Tree for specified source files.
4
+ * @id rust/tools/print-ast
5
+ * @kind graph
6
+ * @tags ast
7
+ */
8
+
9
+ import rust
10
+ private import codeql.rust.printast.PrintAst
11
+ import ExternalPredicates
12
+
13
+ /**
14
+ * Gets a single source file from the comma-separated list.
15
+ */
16
+ string getSelectedSourceFile() {
17
+ exists(string s | selectedSourceFiles(s) | result = s.splitAt(",").trim())
18
+ }
19
+
20
+ /**
21
+ * Gets a file by matching against the selected source file paths.
22
+ */
23
+ File getSelectedFile() {
24
+ exists(string selectedFile |
25
+ selectedFile = getSelectedSourceFile() and
26
+ (
27
+ // Match by exact relative path from source root
28
+ result.getRelativePath() = selectedFile
29
+ or
30
+ // Match by file name if no path separators
31
+ not selectedFile.matches("%/%") and result.getBaseName() = selectedFile
32
+ or
33
+ // Match by ending path component
34
+ result.getAbsolutePath().suffix(result.getAbsolutePath().length() - selectedFile.length()) =
35
+ selectedFile
36
+ )
37
+ )
38
+ }
39
+
40
+ /**
41
+ * Holds if a locatable element should be printed in the AST output.
42
+ * Restricts output to elements from the selected file.
43
+ */
44
+ predicate shouldPrint(Locatable e) { e.getLocation().getFile() = getSelectedFile() }
45
+
46
+ import PrintAst<shouldPrint/1>
@@ -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/)
@@ -0,0 +1,58 @@
1
+ /**
2
+ * @name Print CFG for rust
3
+ * @description Produces a representation of a file's Control Flow Graph for specified source files.
4
+ * @id rust/tools/print-cfg
5
+ * @kind graph
6
+ * @tags cfg
7
+ */
8
+
9
+ import rust
10
+ import codeql.rust.controlflow.ControlFlowGraph
11
+ import ExternalPredicates
12
+
13
+ /**
14
+ * Gets a single source file from the comma-separated list.
15
+ */
16
+ string getSelectedSourceFile() {
17
+ exists(string s | selectedSourceFiles(s) | result = s.splitAt(",").trim())
18
+ }
19
+
20
+ /**
21
+ * Gets a file by matching against the selected source file paths.
22
+ */
23
+ File getSelectedFile() {
24
+ exists(string selectedFile |
25
+ selectedFile = getSelectedSourceFile() and
26
+ (
27
+ // Match by exact relative path from source root
28
+ result.getRelativePath() = selectedFile
29
+ or
30
+ // Match by file name if no path separators
31
+ not selectedFile.matches("%/%") and result.getBaseName() = selectedFile
32
+ or
33
+ // Match by ending path component
34
+ result.getAbsolutePath().suffix(result.getAbsolutePath().length() - selectedFile.length()) =
35
+ selectedFile
36
+ )
37
+ )
38
+ }
39
+
40
+ /**
41
+ * Holds if this CFG node should be included in output.
42
+ */
43
+ predicate shouldPrintNode(CfgNode node) { node.getLocation().getFile() = getSelectedFile() }
44
+
45
+ /**
46
+ * Configuration for PrintCFG that outputs filtered CFG nodes and edges.
47
+ */
48
+ query predicate nodes(CfgNode node, string property, string value) {
49
+ shouldPrintNode(node) and
50
+ property = "semmle.label" and
51
+ value = node.toString()
52
+ }
53
+
54
+ query predicate edges(CfgNode pred, CfgNode succ) {
55
+ shouldPrintNode(pred) and
56
+ shouldPrintNode(succ) and
57
+ pred.getASuccessor() = succ
58
+ }