From 098d9d77b45749aeb7514c1cea2b750791ead85e Mon Sep 17 00:00:00 2001 From: Ryo Yoshida Date: Tue, 14 Feb 2023 17:34:14 +0900 Subject: [PATCH 1/2] Search raw identifiers without prefix --- crates/ide-db/src/search.rs | 23 ++++++++++++++--------- crates/ide/src/references.rs | 15 +++++++++++++++ crates/ide/src/rename.rs | 5 ++++- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/crates/ide-db/src/search.rs b/crates/ide-db/src/search.rs index ada2821d6b1..d09c91942f2 100644 --- a/crates/ide-db/src/search.rs +++ b/crates/ide-db/src/search.rs @@ -455,15 +455,20 @@ impl<'a> FindUsages<'a> { } let find_nodes = move |name: &str, node: &syntax::SyntaxNode, offset: TextSize| { - node.token_at_offset(offset).find(|it| it.text() == name).map(|token| { - // FIXME: There should be optimization potential here - // Currently we try to descend everything we find which - // means we call `Semantics::descend_into_macros` on - // every textual hit. That function is notoriously - // expensive even for things that do not get down mapped - // into macros. - sema.descend_into_macros(token).into_iter().filter_map(|it| it.parent()) - }) + node.token_at_offset(offset) + .find(|it| { + // `name` is stripped of raw ident prefix. See the comment on name retrieval above. + it.text().trim_start_matches("r#") == name + }) + .map(|token| { + // FIXME: There should be optimization potential here + // Currently we try to descend everything we find which + // means we call `Semantics::descend_into_macros` on + // every textual hit. That function is notoriously + // expensive even for things that do not get down mapped + // into macros. + sema.descend_into_macros(token).into_iter().filter_map(|it| it.parent()) + }) }; for (text, file_id, search_range) in scope_files(sema, &search_scope) { diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs index 60fb1544a8f..cabbc287279 100644 --- a/crates/ide/src/references.rs +++ b/crates/ide/src/references.rs @@ -2016,4 +2016,19 @@ fn method$0() {} "#]], ); } + + #[test] + fn raw_identifier() { + check( + r#" +fn r#fn$0() {} +fn main() { r#fn(); } +"#, + expect![[r#" + r#fn Function FileId(0) 0..12 3..7 + + FileId(0) 25..29 + "#]], + ); + } } diff --git a/crates/ide/src/rename.rs b/crates/ide/src/rename.rs index 8e89160ef5e..c0237e1edd0 100644 --- a/crates/ide/src/rename.rs +++ b/crates/ide/src/rename.rs @@ -1371,7 +1371,6 @@ pub fn baz() {} #[test] fn test_rename_mod_from_raw_ident() { - // FIXME: `r#fn` in path expression is not renamed. check_expect( "foo", r#" @@ -1397,6 +1396,10 @@ pub fn baz() {} insert: "foo", delete: 4..8, }, + Indel { + insert: "foo", + delete: 23..27, + }, ], }, }, From 60fa8fefa6faced4028aecfc81afd73bdfaa5f77 Mon Sep 17 00:00:00 2001 From: Ryo Yoshida Date: Tue, 14 Feb 2023 17:34:19 +0900 Subject: [PATCH 2/2] refactor: reduce nesting --- crates/ide-db/src/search.rs | 61 ++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 34 deletions(-) diff --git a/crates/ide-db/src/search.rs b/crates/ide-db/src/search.rs index d09c91942f2..c18a27f17d2 100644 --- a/crates/ide-db/src/search.rs +++ b/crates/ide-db/src/search.rs @@ -460,7 +460,8 @@ impl<'a> FindUsages<'a> { // `name` is stripped of raw ident prefix. See the comment on name retrieval above. it.text().trim_start_matches("r#") == name }) - .map(|token| { + .into_iter() + .flat_map(|token| { // FIXME: There should be optimization potential here // Currently we try to descend everything we find which // means we call `Semantics::descend_into_macros` on @@ -476,30 +477,23 @@ impl<'a> FindUsages<'a> { // Search for occurrences of the items name for offset in match_indices(&text, finder, search_range) { - if let Some(iter) = find_nodes(name, &tree, offset) { - for name in iter.filter_map(ast::NameLike::cast) { - if match name { - ast::NameLike::NameRef(name_ref) => { - self.found_name_ref(&name_ref, sink) - } - ast::NameLike::Name(name) => self.found_name(&name, sink), - ast::NameLike::Lifetime(lifetime) => { - self.found_lifetime(&lifetime, sink) - } - } { - return; - } + for name in find_nodes(name, &tree, offset).filter_map(ast::NameLike::cast) { + if match name { + ast::NameLike::NameRef(name_ref) => self.found_name_ref(&name_ref, sink), + ast::NameLike::Name(name) => self.found_name(&name, sink), + ast::NameLike::Lifetime(lifetime) => self.found_lifetime(&lifetime, sink), + } { + return; } } } // Search for occurrences of the `Self` referring to our type if let Some((self_ty, finder)) = &include_self_kw_refs { for offset in match_indices(&text, finder, search_range) { - if let Some(iter) = find_nodes("Self", &tree, offset) { - for name_ref in iter.filter_map(ast::NameRef::cast) { - if self.found_self_ty_name_ref(self_ty, &name_ref, sink) { - return; - } + for name_ref in find_nodes("Self", &tree, offset).filter_map(ast::NameRef::cast) + { + if self.found_self_ty_name_ref(self_ty, &name_ref, sink) { + return; } } } @@ -518,21 +512,21 @@ impl<'a> FindUsages<'a> { let tree = Lazy::new(move || sema.parse(file_id).syntax().clone()); for offset in match_indices(&text, finder, search_range) { - if let Some(iter) = find_nodes("super", &tree, offset) { - for name_ref in iter.filter_map(ast::NameRef::cast) { - if self.found_name_ref(&name_ref, sink) { - return; - } + for name_ref in + find_nodes("super", &tree, offset).filter_map(ast::NameRef::cast) + { + if self.found_name_ref(&name_ref, sink) { + return; } } } if let Some(finder) = &is_crate_root { for offset in match_indices(&text, finder, search_range) { - if let Some(iter) = find_nodes("crate", &tree, offset) { - for name_ref in iter.filter_map(ast::NameRef::cast) { - if self.found_name_ref(&name_ref, sink) { - return; - } + for name_ref in + find_nodes("crate", &tree, offset).filter_map(ast::NameRef::cast) + { + if self.found_name_ref(&name_ref, sink) { + return; } } } @@ -571,11 +565,10 @@ impl<'a> FindUsages<'a> { let finder = &Finder::new("self"); for offset in match_indices(&text, finder, search_range) { - if let Some(iter) = find_nodes("self", &tree, offset) { - for name_ref in iter.filter_map(ast::NameRef::cast) { - if self.found_self_module_name_ref(&name_ref, sink) { - return; - } + for name_ref in find_nodes("self", &tree, offset).filter_map(ast::NameRef::cast) + { + if self.found_self_module_name_ref(&name_ref, sink) { + return; } } }