mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-26 11:55:04 +00:00
Merge #10698
10698: implement multi-token mapping for ssr r=Veykril a=spookyvision Co-authored-by: Anatol Ulrich <anatol.ulrich@ferrous-systems.com>
This commit is contained in:
commit
e4ce6c7468
1 changed files with 33 additions and 24 deletions
|
@ -58,7 +58,7 @@ impl<'db> MatchFinder<'db> {
|
||||||
if let Some(resolved_path) = pick_path_for_usages(pattern) {
|
if let Some(resolved_path) = pick_path_for_usages(pattern) {
|
||||||
let definition: Definition = resolved_path.resolution.clone().into();
|
let definition: Definition = resolved_path.resolution.clone().into();
|
||||||
for file_range in self.find_usages(usage_cache, definition).file_ranges() {
|
for file_range in self.find_usages(usage_cache, definition).file_ranges() {
|
||||||
if let Some(node_to_match) = self.find_node_to_match(resolved_path, file_range) {
|
for node_to_match in self.find_nodes_to_match(resolved_path, file_range) {
|
||||||
if !is_search_permitted_ancestors(&node_to_match) {
|
if !is_search_permitted_ancestors(&node_to_match) {
|
||||||
cov_mark::hit!(use_declaration_with_braces);
|
cov_mark::hit!(use_declaration_with_braces);
|
||||||
continue;
|
continue;
|
||||||
|
@ -69,36 +69,45 @@ impl<'db> MatchFinder<'db> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_node_to_match(
|
fn find_nodes_to_match(
|
||||||
&self,
|
&self,
|
||||||
resolved_path: &ResolvedPath,
|
resolved_path: &ResolvedPath,
|
||||||
file_range: FileRange,
|
file_range: FileRange,
|
||||||
) -> Option<SyntaxNode> {
|
) -> Vec<SyntaxNode> {
|
||||||
let file = self.sema.parse(file_range.file_id);
|
let file = self.sema.parse(file_range.file_id);
|
||||||
let depth = resolved_path.depth as usize;
|
let depth = resolved_path.depth as usize;
|
||||||
let offset = file_range.range.start();
|
let offset = file_range.range.start();
|
||||||
if let Some(path) =
|
|
||||||
self.sema.find_node_at_offset_with_descend::<ast::Path>(file.syntax(), offset)
|
let mut paths = self
|
||||||
{
|
.sema
|
||||||
self.sema.ancestors_with_macros(path.syntax().clone()).nth(depth)
|
.find_nodes_at_offset_with_descend::<ast::Path>(file.syntax(), offset)
|
||||||
} else if let Some(path) =
|
.peekable();
|
||||||
self.sema.find_node_at_offset_with_descend::<ast::MethodCallExpr>(file.syntax(), offset)
|
|
||||||
{
|
if paths.peek().is_some() {
|
||||||
// If the pattern contained a path and we found a reference to that path that wasn't
|
paths
|
||||||
// itself a path, but was a method call, then we need to adjust how far up to try
|
.filter_map(|path| {
|
||||||
// matching by how deep the path was within a CallExpr. The structure would have been
|
self.sema.ancestors_with_macros(path.syntax().clone()).nth(depth)
|
||||||
// CallExpr, PathExpr, Path - i.e. a depth offset of 2. We don't need to check if the
|
})
|
||||||
// path was part of a CallExpr because if it wasn't then all that will happen is we'll
|
.collect::<Vec<_>>()
|
||||||
// fail to match, which is the desired behavior.
|
|
||||||
const PATH_DEPTH_IN_CALL_EXPR: usize = 2;
|
|
||||||
if depth < PATH_DEPTH_IN_CALL_EXPR {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
self.sema
|
|
||||||
.ancestors_with_macros(path.syntax().clone())
|
|
||||||
.nth(depth - PATH_DEPTH_IN_CALL_EXPR)
|
|
||||||
} else {
|
} else {
|
||||||
None
|
self.sema
|
||||||
|
.find_nodes_at_offset_with_descend::<ast::MethodCallExpr>(file.syntax(), offset)
|
||||||
|
.filter_map(|path| {
|
||||||
|
// If the pattern contained a path and we found a reference to that path that wasn't
|
||||||
|
// itself a path, but was a method call, then we need to adjust how far up to try
|
||||||
|
// matching by how deep the path was within a CallExpr. The structure would have been
|
||||||
|
// CallExpr, PathExpr, Path - i.e. a depth offset of 2. We don't need to check if the
|
||||||
|
// path was part of a CallExpr because if it wasn't then all that will happen is we'll
|
||||||
|
// fail to match, which is the desired behavior.
|
||||||
|
const PATH_DEPTH_IN_CALL_EXPR: usize = 2;
|
||||||
|
if depth < PATH_DEPTH_IN_CALL_EXPR {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
self.sema
|
||||||
|
.ancestors_with_macros(path.syntax().clone())
|
||||||
|
.nth(depth - PATH_DEPTH_IN_CALL_EXPR)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue