Skip to content

Commit e4ce6c7

Browse files
bors[bot]Anatol Ulrich
and
Anatol Ulrich
authored
Merge #10698
10698: implement multi-token mapping for ssr r=Veykril a=spookyvision Co-authored-by: Anatol Ulrich <[email protected]>
2 parents eebac7b + 69e666f commit e4ce6c7

File tree

1 file changed

+33
-24
lines changed

1 file changed

+33
-24
lines changed

crates/ide_ssr/src/search.rs

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ impl<'db> MatchFinder<'db> {
5858
if let Some(resolved_path) = pick_path_for_usages(pattern) {
5959
let definition: Definition = resolved_path.resolution.clone().into();
6060
for file_range in self.find_usages(usage_cache, definition).file_ranges() {
61-
if let Some(node_to_match) = self.find_node_to_match(resolved_path, file_range) {
61+
for node_to_match in self.find_nodes_to_match(resolved_path, file_range) {
6262
if !is_search_permitted_ancestors(&node_to_match) {
6363
cov_mark::hit!(use_declaration_with_braces);
6464
continue;
@@ -69,36 +69,45 @@ impl<'db> MatchFinder<'db> {
6969
}
7070
}
7171

72-
fn find_node_to_match(
72+
fn find_nodes_to_match(
7373
&self,
7474
resolved_path: &ResolvedPath,
7575
file_range: FileRange,
76-
) -> Option<SyntaxNode> {
76+
) -> Vec<SyntaxNode> {
7777
let file = self.sema.parse(file_range.file_id);
7878
let depth = resolved_path.depth as usize;
7979
let offset = file_range.range.start();
80-
if let Some(path) =
81-
self.sema.find_node_at_offset_with_descend::<ast::Path>(file.syntax(), offset)
82-
{
83-
self.sema.ancestors_with_macros(path.syntax().clone()).nth(depth)
84-
} else if let Some(path) =
85-
self.sema.find_node_at_offset_with_descend::<ast::MethodCallExpr>(file.syntax(), offset)
86-
{
87-
// If the pattern contained a path and we found a reference to that path that wasn't
88-
// itself a path, but was a method call, then we need to adjust how far up to try
89-
// matching by how deep the path was within a CallExpr. The structure would have been
90-
// CallExpr, PathExpr, Path - i.e. a depth offset of 2. We don't need to check if the
91-
// path was part of a CallExpr because if it wasn't then all that will happen is we'll
92-
// fail to match, which is the desired behavior.
93-
const PATH_DEPTH_IN_CALL_EXPR: usize = 2;
94-
if depth < PATH_DEPTH_IN_CALL_EXPR {
95-
return None;
96-
}
97-
self.sema
98-
.ancestors_with_macros(path.syntax().clone())
99-
.nth(depth - PATH_DEPTH_IN_CALL_EXPR)
80+
81+
let mut paths = self
82+
.sema
83+
.find_nodes_at_offset_with_descend::<ast::Path>(file.syntax(), offset)
84+
.peekable();
85+
86+
if paths.peek().is_some() {
87+
paths
88+
.filter_map(|path| {
89+
self.sema.ancestors_with_macros(path.syntax().clone()).nth(depth)
90+
})
91+
.collect::<Vec<_>>()
10092
} else {
101-
None
93+
self.sema
94+
.find_nodes_at_offset_with_descend::<ast::MethodCallExpr>(file.syntax(), offset)
95+
.filter_map(|path| {
96+
// If the pattern contained a path and we found a reference to that path that wasn't
97+
// itself a path, but was a method call, then we need to adjust how far up to try
98+
// matching by how deep the path was within a CallExpr. The structure would have been
99+
// CallExpr, PathExpr, Path - i.e. a depth offset of 2. We don't need to check if the
100+
// path was part of a CallExpr because if it wasn't then all that will happen is we'll
101+
// fail to match, which is the desired behavior.
102+
const PATH_DEPTH_IN_CALL_EXPR: usize = 2;
103+
if depth < PATH_DEPTH_IN_CALL_EXPR {
104+
return None;
105+
}
106+
self.sema
107+
.ancestors_with_macros(path.syntax().clone())
108+
.nth(depth - PATH_DEPTH_IN_CALL_EXPR)
109+
})
110+
.collect::<Vec<_>>()
102111
}
103112
}
104113

0 commit comments

Comments
 (0)