5824: Optimize reference search
 r=matklad a=matklad

bors r+
🤖

Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
bors[bot] 2020-08-19 22:55:54 +00:00 committed by GitHub
commit 844e1aa725
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -203,11 +203,25 @@ pub fn set_scope(mut self, scope: Option<SearchScope>) -> FindUsages<'a> {
}
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> {
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 search_scope = {
@ -219,13 +233,11 @@ pub fn all(self) -> Vec<Reference> {
};
let name = match self.def.name(sema.db) {
None => return Vec::new(),
Some(it) => it.to_string(),
None => return,
};
let pat = name.as_str();
let mut refs = vec![];
for (file_id, search_range) in search_scope {
let text = sema.db.file_text(file_id);
let search_range =
@ -240,10 +252,9 @@ pub fn all(self) -> Vec<Reference> {
}
let name_ref: ast::NameRef =
if let Some(name_ref) = sema.find_node_at_offset_with_descend(&tree, offset) {
name_ref
} else {
continue;
match sema.find_node_at_offset_with_descend(&tree, offset) {
Some(it) => it,
None => continue,
};
match classify_name_ref(&sema, &name_ref) {
@ -256,43 +267,45 @@ pub fn all(self) -> Vec<Reference> {
ReferenceKind::Other
};
let file_range = sema.original_range(name_ref.syntax());
refs.push(Reference {
file_range,
let reference = Reference {
file_range: sema.original_range(name_ref.syntax()),
kind,
access: reference_access(&def, &name_ref),
});
};
if sink(reference) {
return;
}
}
Some(NameRefClass::FieldShorthand { local, field }) => {
match self.def {
Definition::Field(_) if &field == self.def => refs.push(Reference {
let reference = match self.def {
Definition::Field(_) if &field == self.def => Reference {
file_range: self.sema.original_range(name_ref.syntax()),
kind: ReferenceKind::FieldShorthandForField,
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()),
kind: ReferenceKind::FieldShorthandForLocal,
access: reference_access(&Definition::Local(local), &name_ref),
}),
_ => {} // not a usage
},
_ => continue, // not a usage
};
if sink(reference) {
return;
}
}
_ => {} // not a usage
}
}
}
refs
}
}
fn reference_access(def: &Definition, name_ref: &ast::NameRef) -> Option<ReferenceAccess> {
// Only Locals and Fields have accesses for now.
match def {
Definition::Local(_) | Definition::Field(_) => {}
_ => return None,
};
if !matches!(def, Definition::Local(_) | Definition::Field(_)) {
return None;
}
let mode = name_ref.syntax().ancestors().find_map(|node| {
match_ast! {