aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_db
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_db')
-rw-r--r--crates/ide_db/src/search.rs48
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
189pub struct FindUsages<'a> {
190 def: &'a Definition,
191 sema: &'a Semantics<'a, RootDatabase>,
192 scope: Option<SearchScope>,
193}
194
195impl<'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 }),