Skip to content

Commit d3a112d

Browse files
committed
Allow including Self kw references to FindUsages
1 parent 0924888 commit d3a112d

File tree

1 file changed

+39
-4
lines changed

1 file changed

+39
-4
lines changed

crates/ide_db/src/search.rs

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@
44
//! get a super-set of matches. Then, we we confirm each match using precise
55
//! name resolution.
66
7-
use std::{convert::TryInto, mem};
7+
use std::{convert::TryInto, iter, mem};
88

99
use base_db::{FileId, FileRange, SourceDatabase, SourceDatabaseExt};
10-
use hir::{DefWithBody, HasAttrs, HasSource, InFile, ModuleSource, Semantics, Visibility};
10+
use either::Either;
11+
use hir::{
12+
DefWithBody, HasAttrs, HasSource, InFile, ModuleDef, ModuleSource, Semantics, Visibility,
13+
};
1114
use once_cell::unsync::Lazy;
1215
use rustc_hash::FxHashMap;
1316
use syntax::{ast, match_ast, AstNode, TextRange, TextSize};
@@ -295,17 +298,23 @@ impl Definition {
295298
}
296299

297300
pub fn usages<'a>(&'a self, sema: &'a Semantics<RootDatabase>) -> FindUsages<'a> {
298-
FindUsages { def: self, sema, scope: None }
301+
FindUsages { def: self, sema, scope: None, include_self_kw_refs: false }
299302
}
300303
}
301304

302305
pub struct FindUsages<'a> {
303306
def: &'a Definition,
304307
sema: &'a Semantics<'a, RootDatabase>,
305308
scope: Option<SearchScope>,
309+
include_self_kw_refs: bool,
306310
}
307311

308312
impl<'a> FindUsages<'a> {
313+
pub fn include_self_kw_refs(mut self, include: bool) -> FindUsages<'a> {
314+
self.include_self_kw_refs = include;
315+
self
316+
}
317+
309318
pub fn in_scope(self, scope: SearchScope) -> FindUsages<'a> {
310319
self.set_scope(Some(scope))
311320
}
@@ -352,14 +361,22 @@ impl<'a> FindUsages<'a> {
352361
};
353362

354363
let pat = name.as_str();
364+
let search_for_self = self.include_self_kw_refs;
365+
355366
for (file_id, search_range) in search_scope {
356367
let text = sema.db.file_text(file_id);
357368
let search_range =
358369
search_range.unwrap_or_else(|| TextRange::up_to(TextSize::of(text.as_str())));
359370

360371
let tree = Lazy::new(|| sema.parse(file_id).syntax().clone());
361372

362-
for (idx, _) in text.match_indices(pat) {
373+
let matches = text.match_indices(pat).chain(if search_for_self {
374+
Either::Left(text.match_indices("Self"))
375+
} else {
376+
Either::Right(iter::empty())
377+
});
378+
379+
for (idx, _) in matches {
363380
let offset: TextSize = idx.try_into().unwrap();
364381
if !search_range.contains_inclusive(offset) {
365382
continue;
@@ -413,6 +430,24 @@ impl<'a> FindUsages<'a> {
413430
sink: &mut dyn FnMut(FileId, FileReference) -> bool,
414431
) -> bool {
415432
match NameRefClass::classify(self.sema, &name_ref) {
433+
Some(NameRefClass::Definition(Definition::SelfType(impl_))) => {
434+
let ty = impl_.self_ty(self.sema.db);
435+
436+
if let Some(adt) = ty.as_adt() {
437+
if &Definition::ModuleDef(ModuleDef::Adt(adt)) == self.def {
438+
let FileRange { file_id, range } =
439+
self.sema.original_range(name_ref.syntax());
440+
let reference = FileReference {
441+
range,
442+
name: ast::NameLike::NameRef(name_ref.clone()),
443+
access: None,
444+
};
445+
return sink(file_id, reference);
446+
}
447+
}
448+
449+
false
450+
}
416451
Some(NameRefClass::Definition(def)) if &def == self.def => {
417452
let FileRange { file_id, range } = self.sema.original_range(name_ref.syntax());
418453
let reference = FileReference {

0 commit comments

Comments
 (0)