Skip to content

Commit fa1df4c

Browse files
UnboundVariableUnboundVariable
andauthored
[ty] Implemented partial support for "find references" language server feature. (#19475)
This PR adds basic support for the "find all references" language server feature. --------- Co-authored-by: UnboundVariable <[email protected]>
1 parent 89258f1 commit fa1df4c

File tree

11 files changed

+1468
-169
lines changed

11 files changed

+1468
-169
lines changed

crates/ruff_python_ast/src/visitor/source_order.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -235,12 +235,7 @@ impl TraversalSignal {
235235
}
236236

237237
pub fn walk_annotation<'a, V: SourceOrderVisitor<'a> + ?Sized>(visitor: &mut V, expr: &'a Expr) {
238-
let node = AnyNodeRef::from(expr);
239-
if visitor.enter_node(node).is_traverse() {
240-
visitor.visit_expr(expr);
241-
}
242-
243-
visitor.leave_node(node);
238+
visitor.visit_expr(expr);
244239
}
245240

246241
pub fn walk_decorator<'a, V>(visitor: &mut V, decorator: &'a Decorator)

crates/ty_ide/src/find_node.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,7 @@ pub(crate) fn covering_node(root: AnyNodeRef, range: TextRange) -> CoveringNode
5252
if visitor.ancestors.is_empty() {
5353
visitor.ancestors.push(root);
5454
}
55-
CoveringNode {
56-
nodes: visitor.ancestors,
57-
}
55+
CoveringNode::from_ancestors(visitor.ancestors)
5856
}
5957

6058
/// The node with a minimal range that fully contains the search range.
@@ -67,6 +65,12 @@ pub(crate) struct CoveringNode<'a> {
6765
}
6866

6967
impl<'a> CoveringNode<'a> {
68+
/// Creates a new `CoveringNode` from a list of ancestor nodes.
69+
/// The ancestors should be ordered from root to the covering node.
70+
pub(crate) fn from_ancestors(ancestors: Vec<AnyNodeRef<'a>>) -> Self {
71+
Self { nodes: ancestors }
72+
}
73+
7074
/// Returns the covering node found.
7175
pub(crate) fn node(&self) -> AnyNodeRef<'a> {
7276
*self

crates/ty_ide/src/goto.rs

Lines changed: 267 additions & 149 deletions
Large diffs are not rendered by default.

crates/ty_ide/src/lib.rs

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ mod goto_type_definition;
88
mod hover;
99
mod inlay_hints;
1010
mod markup;
11+
mod references;
1112
mod semantic_tokens;
1213
mod signature_help;
1314
mod stub_mapping;
@@ -18,6 +19,7 @@ pub use goto::{goto_declaration, goto_definition, goto_type_definition};
1819
pub use hover::hover;
1920
pub use inlay_hints::inlay_hints;
2021
pub use markup::MarkupKind;
22+
pub use references::references;
2123
pub use semantic_tokens::{
2224
SemanticToken, SemanticTokenModifier, SemanticTokenType, SemanticTokens, semantic_tokens,
2325
};
@@ -86,6 +88,15 @@ pub struct NavigationTarget {
8688
}
8789

8890
impl NavigationTarget {
91+
/// Creates a new `NavigationTarget` where the focus and full range are identical.
92+
pub fn new(file: File, range: TextRange) -> Self {
93+
Self {
94+
file,
95+
focus_range: range,
96+
full_range: range,
97+
}
98+
}
99+
89100
pub fn file(&self) -> File {
90101
self.file
91102
}
@@ -291,6 +302,7 @@ mod tests {
291302
));
292303

293304
let mut cursor: Option<Cursor> = None;
305+
294306
for &Source {
295307
ref path,
296308
ref contents,
@@ -299,19 +311,19 @@ mod tests {
299311
{
300312
db.write_file(path, contents)
301313
.expect("write to memory file system to be successful");
302-
let Some(offset) = cursor_offset else {
303-
continue;
304-
};
305314

306315
let file = system_path_to_file(&db, path).expect("newly written file to existing");
307-
// This assert should generally never trip, since
308-
// we have an assert on `CursorTestBuilder::source`
309-
// to ensure we never have more than one marker.
310-
assert!(
311-
cursor.is_none(),
312-
"found more than one source that contains `<CURSOR>`"
313-
);
314-
cursor = Some(Cursor { file, offset });
316+
317+
if let Some(offset) = cursor_offset {
318+
// This assert should generally never trip, since
319+
// we have an assert on `CursorTestBuilder::source`
320+
// to ensure we never have more than one marker.
321+
assert!(
322+
cursor.is_none(),
323+
"found more than one source that contains `<CURSOR>`"
324+
);
325+
cursor = Some(Cursor { file, offset });
326+
}
315327
}
316328

317329
let search_paths = SearchPathSettings::new(vec![SystemPathBuf::from("/")])

0 commit comments

Comments
 (0)