Skip to content

Commit ae4a425

Browse files
authored
Merge pull request #19605 from hvitved/rust/jump-to-def-extensions
Rust: Extend jump-to-def to include paths and `mod file;` imports
2 parents 7d7ea72 + 3781de7 commit ae4a425

File tree

5 files changed

+62
-25
lines changed

5 files changed

+62
-25
lines changed

rust/ql/lib/codeql/rust/internal/Definitions.qll

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* in the code viewer.
44
*/
55

6+
private import rust
67
private import codeql.rust.elements.Variable
78
private import codeql.rust.elements.Locatable
89
private import codeql.rust.elements.FormatArgsExpr
@@ -12,9 +13,12 @@ private import codeql.rust.elements.MacroCall
1213
private import codeql.rust.elements.NamedFormatArgument
1314
private import codeql.rust.elements.PositionalFormatArgument
1415
private import codeql.Locations
16+
private import codeql.rust.internal.PathResolution
1517

1618
/** An element with an associated definition. */
1719
abstract class Use extends Locatable {
20+
Use() { not this.(AstNode).isFromMacroExpansion() }
21+
1822
/** Gets the definition associated with this element. */
1923
abstract Definition getDefinition();
2024

@@ -30,7 +34,8 @@ private module Cached {
3034
newtype TDef =
3135
TVariable(Variable v) or
3236
TFormatArgsArgName(Name name) { name = any(FormatArgsArg a).getName() } or
33-
TFormatArgsArgIndex(Expr e) { e = any(FormatArgsArg a).getExpr() }
37+
TFormatArgsArgIndex(Expr e) { e = any(FormatArgsArg a).getExpr() } or
38+
TItemNode(ItemNode i)
3439

3540
/**
3641
* Gets an element, of kind `kind`, that element `use` uses, if any.
@@ -51,7 +56,8 @@ class Definition extends Cached::TDef {
5156
Location getLocation() {
5257
result = this.asVariable().getLocation() or
5358
result = this.asName().getLocation() or
54-
result = this.asExpr().getLocation()
59+
result = this.asExpr().getLocation() or
60+
result = this.asItemNode().getLocation()
5561
}
5662

5763
/** Gets this definition as a `Variable` */
@@ -63,11 +69,15 @@ class Definition extends Cached::TDef {
6369
/** Gets this definition as an `Expr` */
6470
Expr asExpr() { this = Cached::TFormatArgsArgIndex(result) }
6571

72+
/** Gets this definition as an `ItemNode` */
73+
ItemNode asItemNode() { this = Cached::TItemNode(result) }
74+
6675
/** Gets the string representation of this element. */
6776
string toString() {
6877
result = this.asExpr().toString() or
6978
result = this.asVariable().toString() or
70-
result = this.asName().getText()
79+
result = this.asName().getText() or
80+
result = this.asItemNode().toString()
7181
}
7282
}
7383

@@ -124,3 +134,20 @@ private class PositionalFormatArgumentUse extends Use instanceof PositionalForma
124134

125135
override string getUseType() { result = "format argument" }
126136
}
137+
138+
private class PathUse extends Use instanceof Path {
139+
override Definition getDefinition() { result.asItemNode() = resolvePath(this) }
140+
141+
override string getUseType() { result = "path" }
142+
}
143+
144+
private class FileUse extends Use instanceof Name {
145+
override Definition getDefinition() {
146+
exists(Module m |
147+
this = m.getName() and
148+
fileImport(m, result.asItemNode())
149+
)
150+
}
151+
152+
override string getUseType() { result = "file" }
153+
}

rust/ql/lib/codeql/rust/internal/PathResolution.qll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1021,7 +1021,8 @@ private predicate pathAttrImport(Folder f, Module m, string relativePath) {
10211021
private predicate shouldAppend(Folder f, string relativePath) { pathAttrImport(f, _, relativePath) }
10221022

10231023
/** Holds if `m` is a `mod name;` item importing file `f`. */
1024-
private predicate fileImport(Module m, SourceFile f) {
1024+
pragma[nomagic]
1025+
predicate fileImport(Module m, SourceFile f) {
10251026
exists(string name, Folder parent |
10261027
modImport0(m, name, _) and
10271028
fileModule(f, name, parent)
Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
1-
| main.rs:2:9:2:13 | width | main.rs:5:29:5:33 | width | local variable |
2-
| main.rs:2:9:2:13 | width | main.rs:6:41:6:45 | width | local variable |
3-
| main.rs:2:9:2:13 | width | main.rs:7:36:7:40 | width | local variable |
4-
| main.rs:3:9:3:17 | precision | main.rs:5:36:5:44 | precision | local variable |
5-
| main.rs:3:9:3:17 | precision | main.rs:6:48:6:56 | precision | local variable |
6-
| main.rs:4:9:4:13 | value | main.rs:6:34:6:38 | value | local variable |
7-
| main.rs:4:9:4:13 | value | main.rs:7:29:7:33 | value | local variable |
8-
| main.rs:5:50:5:54 | value | main.rs:5:22:5:26 | value | format argument |
9-
| main.rs:6:34:6:38 | value | main.rs:6:22:6:22 | 0 | format argument |
10-
| main.rs:6:41:6:45 | width | main.rs:6:25:6:25 | 1 | format argument |
11-
| main.rs:6:48:6:56 | precision | main.rs:6:28:6:28 | 2 | format argument |
12-
| main.rs:7:29:7:33 | value | main.rs:7:21:7:22 | {} | format argument |
13-
| main.rs:7:36:7:40 | width | main.rs:7:24:7:25 | {} | format argument |
14-
| main.rs:8:9:8:14 | people | main.rs:9:22:9:27 | people | local variable |
15-
| main.rs:10:31:10:31 | 1 | main.rs:10:19:10:20 | {} | format argument |
16-
| main.rs:10:31:10:31 | 1 | main.rs:10:23:10:23 | 0 | format argument |
17-
| main.rs:10:34:10:34 | 2 | main.rs:10:16:10:16 | 1 | format argument |
18-
| main.rs:10:34:10:34 | 2 | main.rs:10:26:10:27 | {} | format argument |
19-
| main.rs:11:40:11:42 | "x" | main.rs:11:31:11:35 | {:<5} | format argument |
1+
| main.rs:3:5:3:7 | lib | lib.rs:1:1:1:1 | SourceFile | file |
2+
| main.rs:9:22:9:26 | value | main.rs:9:50:9:54 | value | format argument |
3+
| main.rs:9:29:9:33 | width | main.rs:6:9:6:13 | width | local variable |
4+
| main.rs:9:36:9:44 | precision | main.rs:7:9:7:17 | precision | local variable |
5+
| main.rs:10:22:10:22 | 0 | main.rs:10:34:10:38 | value | format argument |
6+
| main.rs:10:25:10:25 | 1 | main.rs:10:41:10:45 | width | format argument |
7+
| main.rs:10:28:10:28 | 2 | main.rs:10:48:10:56 | precision | format argument |
8+
| main.rs:10:34:10:38 | value | main.rs:8:9:8:13 | value | local variable |
9+
| main.rs:10:41:10:45 | width | main.rs:6:9:6:13 | width | local variable |
10+
| main.rs:10:48:10:56 | precision | main.rs:7:9:7:17 | precision | local variable |
11+
| main.rs:11:21:11:22 | {} | main.rs:11:29:11:33 | value | format argument |
12+
| main.rs:11:24:11:25 | {} | main.rs:11:36:11:40 | width | format argument |
13+
| main.rs:11:29:11:33 | value | main.rs:8:9:8:13 | value | local variable |
14+
| main.rs:11:36:11:40 | width | main.rs:6:9:6:13 | width | local variable |
15+
| main.rs:13:22:13:27 | people | main.rs:12:9:12:14 | people | local variable |
16+
| main.rs:14:16:14:16 | 1 | main.rs:14:34:14:34 | 2 | format argument |
17+
| main.rs:14:19:14:20 | {} | main.rs:14:31:14:31 | 1 | format argument |
18+
| main.rs:14:23:14:23 | 0 | main.rs:14:31:14:31 | 1 | format argument |
19+
| main.rs:14:26:14:27 | {} | main.rs:14:34:14:34 | 2 | format argument |
20+
| main.rs:15:31:15:35 | {:<5} | main.rs:15:40:15:42 | "x" | format argument |
21+
| main.rs:16:13:16:13 | S | main.rs:1:1:1:9 | struct S | path |
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import codeql.rust.internal.Definitions
22

33
from Definition def, Use use, string kind
4-
where def = definitionOf(use, kind)
5-
select def, use, kind
4+
where
5+
def = definitionOf(use, kind) and
6+
use.fromSource()
7+
select use, def, kind

rust/ql/test/library-tests/definitions/main.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
struct S;
2+
3+
mod lib;
4+
15
fn main() {
26
let width = 4;
37
let precision = 2;
@@ -9,4 +13,5 @@ fn main() {
913
println!("Hello {people}!");
1014
println!("{1} {} {0} {}", 1, 2);
1115
assert_eq!(format!("Hello {:<5}!", "x"), "Hello x !");
16+
let x = S;
1217
}

0 commit comments

Comments
 (0)