aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ssr/src/search.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ssr/src/search.rs')
-rw-r--r--crates/ra_ssr/src/search.rs29
1 files changed, 28 insertions, 1 deletions
diff --git a/crates/ra_ssr/src/search.rs b/crates/ra_ssr/src/search.rs
index 9a4e35e96..141e7d026 100644
--- a/crates/ra_ssr/src/search.rs
+++ b/crates/ra_ssr/src/search.rs
@@ -10,7 +10,8 @@ use ra_ide_db::{
10 defs::Definition, 10 defs::Definition,
11 search::{Reference, SearchScope}, 11 search::{Reference, SearchScope},
12}; 12};
13use ra_syntax::{ast, AstNode, SyntaxNode}; 13use ra_syntax::{ast, AstNode, SyntaxKind, SyntaxNode};
14use test_utils::mark;
14 15
15/// A cache for the results of find_usages. This is for when we have multiple patterns that have the 16/// A cache for the results of find_usages. This is for when we have multiple patterns that have the
16/// same path. e.g. if the pattern was `foo::Bar` that can parse as a path, an expression, a type 17/// same path. e.g. if the pattern was `foo::Bar` that can parse as a path, an expression, a type
@@ -59,6 +60,10 @@ impl<'db> MatchFinder<'db> {
59 .skip(first_path.depth as usize) 60 .skip(first_path.depth as usize)
60 .next() 61 .next()
61 { 62 {
63 if !is_search_permitted_ancestors(&node_to_match) {
64 mark::hit!(use_declaration_with_braces);
65 continue;
66 }
62 if let Ok(m) = 67 if let Ok(m) =
63 matching::get_match(false, rule, &node_to_match, &None, &self.sema) 68 matching::get_match(false, rule, &node_to_match, &None, &self.sema)
64 { 69 {
@@ -123,6 +128,9 @@ impl<'db> MatchFinder<'db> {
123 restrict_range: &Option<FileRange>, 128 restrict_range: &Option<FileRange>,
124 matches_out: &mut Vec<Match>, 129 matches_out: &mut Vec<Match>,
125 ) { 130 ) {
131 if !is_search_permitted(code) {
132 return;
133 }
126 if let Ok(m) = matching::get_match(false, rule, &code, restrict_range, &self.sema) { 134 if let Ok(m) = matching::get_match(false, rule, &code, restrict_range, &self.sema) {
127 matches_out.push(m); 135 matches_out.push(m);
128 } 136 }
@@ -149,6 +157,25 @@ impl<'db> MatchFinder<'db> {
149 } 157 }
150} 158}
151 159
160/// Returns whether we support matching within `node` and all of its ancestors.
161fn is_search_permitted_ancestors(node: &SyntaxNode) -> bool {
162 if let Some(parent) = node.parent() {
163 if !is_search_permitted_ancestors(&parent) {
164 return false;
165 }
166 }
167 is_search_permitted(node)
168}
169
170/// Returns whether we support matching within this kind of node.
171fn is_search_permitted(node: &SyntaxNode) -> bool {
172 // FIXME: Properly handle use declarations. At the moment, if our search pattern is `foo::bar`
173 // and the code is `use foo::{baz, bar}`, we'll match `bar`, since it resolves to `foo::bar`.
174 // However we'll then replace just the part we matched `bar`. We probably need to instead remove
175 // `bar` and insert a new use declaration.
176 node.kind() != SyntaxKind::USE_ITEM
177}
178
152impl UsageCache { 179impl UsageCache {
153 fn find(&mut self, definition: &Definition) -> Option<&[Reference]> { 180 fn find(&mut self, definition: &Definition) -> Option<&[Reference]> {
154 // We expect a very small number of cache entries (generally 1), so a linear scan should be 181 // We expect a very small number of cache entries (generally 1), so a linear scan should be