aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_ide/src/references.rs7
-rw-r--r--crates/ra_ide_db/src/search.rs125
2 files changed, 67 insertions, 65 deletions
diff --git a/crates/ra_ide/src/references.rs b/crates/ra_ide/src/references.rs
index abecca2bb..6440707d7 100644
--- a/crates/ra_ide/src/references.rs
+++ b/crates/ra_ide/src/references.rs
@@ -28,9 +28,7 @@ use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeI
28 28
29pub(crate) use self::rename::rename; 29pub(crate) use self::rename::rename;
30 30
31pub use ra_ide_db::search::{ 31pub use ra_ide_db::search::{Reference, ReferenceAccess, ReferenceKind, SearchScope};
32 find_refs_to_def, Reference, ReferenceAccess, ReferenceKind, SearchScope,
33};
34 32
35#[derive(Debug, Clone)] 33#[derive(Debug, Clone)]
36pub struct ReferenceSearchResult { 34pub struct ReferenceSearchResult {
@@ -105,7 +103,8 @@ pub(crate) fn find_all_refs(
105 103
106 let RangeInfo { range, info: def } = find_name(&sema, &syntax, position, opt_name)?; 104 let RangeInfo { range, info: def } = find_name(&sema, &syntax, position, opt_name)?;
107 105
108 let references = find_refs_to_def(db, &def, search_scope) 106 let references = def
107 .find_usages(db, search_scope)
109 .into_iter() 108 .into_iter()
110 .filter(|r| search_kind == ReferenceKind::Other || search_kind == r.kind) 109 .filter(|r| search_kind == ReferenceKind::Other || search_kind == r.kind)
111 .collect(); 110 .collect();
diff --git a/crates/ra_ide_db/src/search.rs b/crates/ra_ide_db/src/search.rs
index efd43f4c1..23dd278b5 100644
--- a/crates/ra_ide_db/src/search.rs
+++ b/crates/ra_ide_db/src/search.rs
@@ -171,85 +171,88 @@ impl IntoIterator for SearchScope {
171 } 171 }
172} 172}
173 173
174pub fn find_refs_to_def( 174impl Definition {
175 db: &RootDatabase, 175 pub fn find_usages(
176 def: &Definition, 176 &self,
177 search_scope: Option<SearchScope>, 177 db: &RootDatabase,
178) -> Vec<Reference> { 178 search_scope: Option<SearchScope>,
179 let _p = profile("find_refs_to_def"); 179 ) -> Vec<Reference> {
180 180 let _p = profile("Definition::find_usages");
181 let search_scope = { 181
182 let base = SearchScope::for_def(&def, db); 182 let search_scope = {
183 match search_scope { 183 let base = SearchScope::for_def(self, db);
184 None => base, 184 match search_scope {
185 Some(scope) => base.intersection(&scope), 185 None => base,
186 } 186 Some(scope) => base.intersection(&scope),
187 }; 187 }
188 };
188 189
189 let name = match def.name(db) { 190 let name = match self.name(db) {
190 None => return Vec::new(), 191 None => return Vec::new(),
191 Some(it) => it.to_string(), 192 Some(it) => it.to_string(),
192 }; 193 };
193 194
194 let pat = name.as_str(); 195 let pat = name.as_str();
195 let mut refs = vec![]; 196 let mut refs = vec![];
196 197
197 for (file_id, search_range) in search_scope { 198 for (file_id, search_range) in search_scope {
198 let text = db.file_text(file_id); 199 let text = db.file_text(file_id);
199 let search_range = 200 let search_range =
200 search_range.unwrap_or(TextRange::offset_len(0.into(), TextUnit::of_str(&text))); 201 search_range.unwrap_or(TextRange::offset_len(0.into(), TextUnit::of_str(&text)));
201 202
202 let sema = Semantics::new(db); 203 let sema = Semantics::new(db);
203 let tree = Lazy::new(|| sema.parse(file_id).syntax().clone()); 204 let tree = Lazy::new(|| sema.parse(file_id).syntax().clone());
204 205
205 for (idx, _) in text.match_indices(pat) { 206 for (idx, _) in text.match_indices(pat) {
206 let offset = TextUnit::from_usize(idx); 207 let offset = TextUnit::from_usize(idx);
207 if !search_range.contains_inclusive(offset) { 208 if !search_range.contains_inclusive(offset) {
208 // tested_by!(search_filters_by_range); 209 // tested_by!(search_filters_by_range);
209 continue; 210 continue;
210 } 211 }
211 212
212 let name_ref = 213 let name_ref =
213 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(&tree, offset) { 214 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(&tree, offset) {
214 name_ref 215 name_ref
215 } else { 216 } else {
216 // Handle macro token cases 217 // Handle macro token cases
217 let token = match tree.token_at_offset(offset) { 218 let token = match tree.token_at_offset(offset) {
218 TokenAtOffset::None => continue, 219 TokenAtOffset::None => continue,
219 TokenAtOffset::Single(t) => t, 220 TokenAtOffset::Single(t) => t,
220 TokenAtOffset::Between(_, t) => t, 221 TokenAtOffset::Between(_, t) => t,
222 };
223 let expanded = sema.descend_into_macros(token);
224 match ast::NameRef::cast(expanded.parent()) {
225 Some(name_ref) => name_ref,
226 _ => continue,
227 }
221 }; 228 };
222 let expanded = sema.descend_into_macros(token);
223 match ast::NameRef::cast(expanded.parent()) {
224 Some(name_ref) => name_ref,
225 _ => continue,
226 }
227 };
228 229
229 // FIXME: reuse sb 230 // FIXME: reuse sb
230 // See https://github.com/rust-lang/rust/pull/68198#issuecomment-574269098 231 // See https://github.com/rust-lang/rust/pull/68198#issuecomment-574269098
231 232
232 if let Some(d) = classify_name_ref(&sema, &name_ref) { 233 if let Some(d) = classify_name_ref(&sema, &name_ref) {
233 let d = d.definition(); 234 let d = d.definition();
234 if &d == def { 235 if &d == self {
235 let kind = 236 let kind = if is_record_lit_name_ref(&name_ref)
236 if is_record_lit_name_ref(&name_ref) || is_call_expr_name_ref(&name_ref) { 237 || is_call_expr_name_ref(&name_ref)
238 {
237 ReferenceKind::StructLiteral 239 ReferenceKind::StructLiteral
238 } else { 240 } else {
239 ReferenceKind::Other 241 ReferenceKind::Other
240 }; 242 };
241 243
242 let file_range = sema.original_range(name_ref.syntax()); 244 let file_range = sema.original_range(name_ref.syntax());
243 refs.push(Reference { 245 refs.push(Reference {
244 file_range, 246 file_range,
245 kind, 247 kind,
246 access: reference_access(&d, &name_ref), 248 access: reference_access(&d, &name_ref),
247 }); 249 });
250 }
248 } 251 }
249 } 252 }
250 } 253 }
254 refs
251 } 255 }
252 refs
253} 256}
254 257
255fn reference_access(def: &Definition, name_ref: &ast::NameRef) -> Option<ReferenceAccess> { 258fn reference_access(def: &Definition, name_ref: &ast::NameRef) -> Option<ReferenceAccess> {