diff options
-rw-r--r-- | crates/ra_ide/src/references.rs | 7 | ||||
-rw-r--r-- | crates/ra_ide_db/src/search.rs | 125 |
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 | ||
29 | pub(crate) use self::rename::rename; | 29 | pub(crate) use self::rename::rename; |
30 | 30 | ||
31 | pub use ra_ide_db::search::{ | 31 | pub 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)] |
36 | pub struct ReferenceSearchResult { | 34 | pub 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 | ||
174 | pub fn find_refs_to_def( | 174 | impl 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 | ||
255 | fn reference_access(def: &Definition, name_ref: &ast::NameRef) -> Option<ReferenceAccess> { | 258 | fn reference_access(def: &Definition, name_ref: &ast::NameRef) -> Option<ReferenceAccess> { |