mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-03 15:15:24 +00:00
Merge #5824
5824: Optimize reference search
r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
844e1aa725
1 changed files with 38 additions and 25 deletions
|
@ -203,11 +203,25 @@ impl<'a> FindUsages<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn at_least_one(self) -> bool {
|
pub fn at_least_one(self) -> bool {
|
||||||
!self.all().is_empty()
|
let mut found = false;
|
||||||
|
self.search(&mut |_reference| {
|
||||||
|
found = true;
|
||||||
|
true
|
||||||
|
});
|
||||||
|
found
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn all(self) -> Vec<Reference> {
|
pub fn all(self) -> Vec<Reference> {
|
||||||
let _p = profile::span("Definition::find_usages");
|
let mut res = Vec::new();
|
||||||
|
self.search(&mut |reference| {
|
||||||
|
res.push(reference);
|
||||||
|
false
|
||||||
|
});
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn search(self, sink: &mut dyn FnMut(Reference) -> bool) {
|
||||||
|
let _p = profile::span("FindUsages:search");
|
||||||
let sema = self.sema;
|
let sema = self.sema;
|
||||||
|
|
||||||
let search_scope = {
|
let search_scope = {
|
||||||
|
@ -219,13 +233,11 @@ impl<'a> FindUsages<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let name = match self.def.name(sema.db) {
|
let name = match self.def.name(sema.db) {
|
||||||
None => return Vec::new(),
|
|
||||||
Some(it) => it.to_string(),
|
Some(it) => it.to_string(),
|
||||||
|
None => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
let pat = name.as_str();
|
let pat = name.as_str();
|
||||||
let mut refs = vec![];
|
|
||||||
|
|
||||||
for (file_id, search_range) in search_scope {
|
for (file_id, search_range) in search_scope {
|
||||||
let text = sema.db.file_text(file_id);
|
let text = sema.db.file_text(file_id);
|
||||||
let search_range =
|
let search_range =
|
||||||
|
@ -240,10 +252,9 @@ impl<'a> FindUsages<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let name_ref: ast::NameRef =
|
let name_ref: ast::NameRef =
|
||||||
if let Some(name_ref) = sema.find_node_at_offset_with_descend(&tree, offset) {
|
match sema.find_node_at_offset_with_descend(&tree, offset) {
|
||||||
name_ref
|
Some(it) => it,
|
||||||
} else {
|
None => continue,
|
||||||
continue;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
match classify_name_ref(&sema, &name_ref) {
|
match classify_name_ref(&sema, &name_ref) {
|
||||||
|
@ -256,43 +267,45 @@ impl<'a> FindUsages<'a> {
|
||||||
ReferenceKind::Other
|
ReferenceKind::Other
|
||||||
};
|
};
|
||||||
|
|
||||||
let file_range = sema.original_range(name_ref.syntax());
|
let reference = Reference {
|
||||||
refs.push(Reference {
|
file_range: sema.original_range(name_ref.syntax()),
|
||||||
file_range,
|
|
||||||
kind,
|
kind,
|
||||||
access: reference_access(&def, &name_ref),
|
access: reference_access(&def, &name_ref),
|
||||||
});
|
};
|
||||||
|
if sink(reference) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Some(NameRefClass::FieldShorthand { local, field }) => {
|
Some(NameRefClass::FieldShorthand { local, field }) => {
|
||||||
match self.def {
|
let reference = match self.def {
|
||||||
Definition::Field(_) if &field == self.def => refs.push(Reference {
|
Definition::Field(_) if &field == self.def => Reference {
|
||||||
file_range: self.sema.original_range(name_ref.syntax()),
|
file_range: self.sema.original_range(name_ref.syntax()),
|
||||||
kind: ReferenceKind::FieldShorthandForField,
|
kind: ReferenceKind::FieldShorthandForField,
|
||||||
access: reference_access(&field, &name_ref),
|
access: reference_access(&field, &name_ref),
|
||||||
}),
|
},
|
||||||
Definition::Local(l) if &local == l => refs.push(Reference {
|
Definition::Local(l) if &local == l => Reference {
|
||||||
file_range: self.sema.original_range(name_ref.syntax()),
|
file_range: self.sema.original_range(name_ref.syntax()),
|
||||||
kind: ReferenceKind::FieldShorthandForLocal,
|
kind: ReferenceKind::FieldShorthandForLocal,
|
||||||
access: reference_access(&Definition::Local(local), &name_ref),
|
access: reference_access(&Definition::Local(local), &name_ref),
|
||||||
}),
|
},
|
||||||
|
_ => continue, // not a usage
|
||||||
_ => {} // not a usage
|
|
||||||
};
|
};
|
||||||
|
if sink(reference) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {} // not a usage
|
_ => {} // not a usage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
refs
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reference_access(def: &Definition, name_ref: &ast::NameRef) -> Option<ReferenceAccess> {
|
fn reference_access(def: &Definition, name_ref: &ast::NameRef) -> Option<ReferenceAccess> {
|
||||||
// Only Locals and Fields have accesses for now.
|
// Only Locals and Fields have accesses for now.
|
||||||
match def {
|
if !matches!(def, Definition::Local(_) | Definition::Field(_)) {
|
||||||
Definition::Local(_) | Definition::Field(_) => {}
|
return None;
|
||||||
_ => return None,
|
}
|
||||||
};
|
|
||||||
|
|
||||||
let mode = name_ref.syntax().ancestors().find_map(|node| {
|
let mode = name_ref.syntax().ancestors().find_map(|node| {
|
||||||
match_ast! {
|
match_ast! {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue