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:
bors[bot] 2021-11-07 11:02:39 +00:00 committed by GitHub
commit e4ce6c7468
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -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,21 +69,30 @@ 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
.find_nodes_at_offset_with_descend::<ast::Path>(file.syntax(), offset)
.peekable();
if paths.peek().is_some() {
paths
.filter_map(|path| {
self.sema.ancestors_with_macros(path.syntax().clone()).nth(depth) self.sema.ancestors_with_macros(path.syntax().clone()).nth(depth)
} else if let Some(path) = })
self.sema.find_node_at_offset_with_descend::<ast::MethodCallExpr>(file.syntax(), offset) .collect::<Vec<_>>()
{ } else {
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 // 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 // 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 // matching by how deep the path was within a CallExpr. The structure would have been
@ -97,8 +106,8 @@ impl<'db> MatchFinder<'db> {
self.sema self.sema
.ancestors_with_macros(path.syntax().clone()) .ancestors_with_macros(path.syntax().clone())
.nth(depth - PATH_DEPTH_IN_CALL_EXPR) .nth(depth - PATH_DEPTH_IN_CALL_EXPR)
} else { })
None .collect::<Vec<_>>()
} }
} }