diff options
| author | Anatol Ulrich <anatol.ulrich@ferrous-systems.com> | 2021-11-04 22:01:59 +0100 |
|---|---|---|
| committer | Anatol Ulrich <anatol.ulrich@ferrous-systems.com> | 2021-11-04 22:01:59 +0100 |
| commit | 69e666fdbaaec1a4e9b9b0e9643a8dbfbb51cb89 (patch) | |
| tree | 679882781925acee21ad86116556657c79c86378 | |
| parent | c96481e25f08d1565cb9b3cac89323216e6f8d7f (diff) | |
| download | rust-69e666fdbaaec1a4e9b9b0e9643a8dbfbb51cb89.tar.gz rust-69e666fdbaaec1a4e9b9b0e9643a8dbfbb51cb89.zip | |
maybe?
| -rw-r--r-- | crates/ide_ssr/src/search.rs | 57 |
1 files changed, 33 insertions, 24 deletions
diff --git a/crates/ide_ssr/src/search.rs b/crates/ide_ssr/src/search.rs index 42ce85eebe6..ffecffc46d6 100644 --- a/crates/ide_ssr/src/search.rs +++ b/crates/ide_ssr/src/search.rs @@ -58,7 +58,7 @@ impl<'db> MatchFinder<'db> { if let Some(resolved_path) = pick_path_for_usages(pattern) { let definition: Definition = resolved_path.resolution.clone().into(); 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) { cov_mark::hit!(use_declaration_with_braces); continue; @@ -69,36 +69,45 @@ impl<'db> MatchFinder<'db> { } } - fn find_node_to_match( + fn find_nodes_to_match( &self, resolved_path: &ResolvedPath, file_range: FileRange, - ) -> Option<SyntaxNode> { + ) -> Vec<SyntaxNode> { let file = self.sema.parse(file_range.file_id); let depth = resolved_path.depth as usize; let offset = file_range.range.start(); - if let Some(path) = - self.sema.find_node_at_offset_with_descend::<ast::Path>(file.syntax(), offset) - { - 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) - { - // 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) + + 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) + }) + .collect::<Vec<_>>() } 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<_>>() } } |
