diff options
author | Aleksey Kladov <[email protected]> | 2020-08-19 17:58:48 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2020-08-19 17:58:48 +0100 |
commit | 81b0976187d73eba4f9b14d8a0b8539ab8f06dcd (patch) | |
tree | 15017f0b41ea44614d603f0b9e029e7bc86a5c44 /crates/ide_db | |
parent | 686a6a26fd2263e4bb958fbcf94b04244ed73e08 (diff) |
Future proof find-usages API
We might want to provide more efficient impls for check if usages
exist, limiting the search, filtering and cancellation, so let's
violate YAGNI a bit here.
Diffstat (limited to 'crates/ide_db')
-rw-r--r-- | crates/ide_db/src/search.rs | 48 |
1 files changed, 35 insertions, 13 deletions
diff --git a/crates/ide_db/src/search.rs b/crates/ide_db/src/search.rs index b9360bf12..ce7631c69 100644 --- a/crates/ide_db/src/search.rs +++ b/crates/ide_db/src/search.rs | |||
@@ -181,22 +181,44 @@ impl Definition { | |||
181 | SearchScope::new(res) | 181 | SearchScope::new(res) |
182 | } | 182 | } |
183 | 183 | ||
184 | pub fn find_usages( | 184 | pub fn usages<'a>(&'a self, sema: &'a Semantics<RootDatabase>) -> FindUsages<'a> { |
185 | &self, | 185 | FindUsages { def: self, sema, scope: None } |
186 | sema: &Semantics<RootDatabase>, | 186 | } |
187 | search_scope: Option<SearchScope>, | 187 | } |
188 | ) -> Vec<Reference> { | 188 | |
189 | pub struct FindUsages<'a> { | ||
190 | def: &'a Definition, | ||
191 | sema: &'a Semantics<'a, RootDatabase>, | ||
192 | scope: Option<SearchScope>, | ||
193 | } | ||
194 | |||
195 | impl<'a> FindUsages<'a> { | ||
196 | pub fn in_scope(self, scope: SearchScope) -> FindUsages<'a> { | ||
197 | self.set_scope(Some(scope)) | ||
198 | } | ||
199 | pub fn set_scope(mut self, scope: Option<SearchScope>) -> FindUsages<'a> { | ||
200 | assert!(self.scope.is_none()); | ||
201 | self.scope = scope; | ||
202 | self | ||
203 | } | ||
204 | |||
205 | pub fn at_least_one(self) -> bool { | ||
206 | self.all().is_empty() | ||
207 | } | ||
208 | |||
209 | pub fn all(self) -> Vec<Reference> { | ||
189 | let _p = profile::span("Definition::find_usages"); | 210 | let _p = profile::span("Definition::find_usages"); |
211 | let sema = self.sema; | ||
190 | 212 | ||
191 | let search_scope = { | 213 | let search_scope = { |
192 | let base = self.search_scope(sema.db); | 214 | let base = self.def.search_scope(sema.db); |
193 | match search_scope { | 215 | match self.scope { |
194 | None => base, | 216 | None => base, |
195 | Some(scope) => base.intersection(&scope), | 217 | Some(scope) => base.intersection(&scope), |
196 | } | 218 | } |
197 | }; | 219 | }; |
198 | 220 | ||
199 | let name = match self.name(sema.db) { | 221 | let name = match self.def.name(sema.db) { |
200 | None => return Vec::new(), | 222 | None => return Vec::new(), |
201 | Some(it) => it.to_string(), | 223 | Some(it) => it.to_string(), |
202 | }; | 224 | }; |
@@ -225,7 +247,7 @@ impl Definition { | |||
225 | }; | 247 | }; |
226 | 248 | ||
227 | match classify_name_ref(&sema, &name_ref) { | 249 | match classify_name_ref(&sema, &name_ref) { |
228 | Some(NameRefClass::Definition(def)) if &def == self => { | 250 | Some(NameRefClass::Definition(def)) if &def == self.def => { |
229 | let kind = if is_record_lit_name_ref(&name_ref) | 251 | let kind = if is_record_lit_name_ref(&name_ref) |
230 | || is_call_expr_name_ref(&name_ref) | 252 | || is_call_expr_name_ref(&name_ref) |
231 | { | 253 | { |
@@ -242,14 +264,14 @@ impl Definition { | |||
242 | }); | 264 | }); |
243 | } | 265 | } |
244 | Some(NameRefClass::FieldShorthand { local, field }) => { | 266 | Some(NameRefClass::FieldShorthand { local, field }) => { |
245 | match self { | 267 | match self.def { |
246 | Definition::Field(_) if &field == self => refs.push(Reference { | 268 | Definition::Field(_) if &field == self.def => refs.push(Reference { |
247 | file_range: sema.original_range(name_ref.syntax()), | 269 | file_range: self.sema.original_range(name_ref.syntax()), |
248 | kind: ReferenceKind::FieldShorthandForField, | 270 | kind: ReferenceKind::FieldShorthandForField, |
249 | access: reference_access(&field, &name_ref), | 271 | access: reference_access(&field, &name_ref), |
250 | }), | 272 | }), |
251 | Definition::Local(l) if &local == l => refs.push(Reference { | 273 | Definition::Local(l) if &local == l => refs.push(Reference { |
252 | file_range: sema.original_range(name_ref.syntax()), | 274 | file_range: self.sema.original_range(name_ref.syntax()), |
253 | kind: ReferenceKind::FieldShorthandForLocal, | 275 | kind: ReferenceKind::FieldShorthandForLocal, |
254 | access: reference_access(&Definition::Local(local), &name_ref), | 276 | access: reference_access(&Definition::Local(local), &name_ref), |
255 | }), | 277 | }), |