From 532e178f8e1fd3e20d1a22256d93cad2ba9954a9 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sun, 22 Mar 2020 19:52:14 +0800 Subject: Add find_node_at_offset_with_descend --- crates/ra_hir/src/semantics.rs | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'crates') diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs index 55e634528..caece91c1 100644 --- a/crates/ra_hir/src/semantics.rs +++ b/crates/ra_hir/src/semantics.rs @@ -12,7 +12,8 @@ use hir_expand::ExpansionInfo; use ra_db::{FileId, FileRange}; use ra_prof::profile; use ra_syntax::{ - algo::skip_trivia_token, ast, AstNode, Direction, SyntaxNode, SyntaxToken, TextRange, TextUnit, + algo::{find_node_at_offset, skip_trivia_token}, + ast, AstNode, Direction, SyntaxNode, SyntaxToken, TextRange, TextUnit, }; use rustc_hash::{FxHashMap, FxHashSet}; @@ -108,6 +109,17 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { token.value } + pub fn descend_node_at_offset( + &self, + node: &SyntaxNode, + offset: TextUnit, + ) -> Option { + // Handle macro token cases + node.token_at_offset(offset) + .map(|token| self.descend_into_macros(token)) + .find_map(|it| self.ancestors_with_macros(it.parent()).find_map(N::cast)) + } + pub fn original_range(&self, node: &SyntaxNode) -> FileRange { let node = self.find_file(node.clone()); original_range(self.db, node.as_ref()) @@ -129,6 +141,8 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { .kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len()) } + /// Find a AstNode by offset inside SyntaxNode, if it is inside *Macrofile*, + /// search up until it is target AstNode type pub fn find_node_at_offset_with_macros( &self, node: &SyntaxNode, @@ -137,6 +151,19 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { self.ancestors_at_offset_with_macros(node, offset).find_map(N::cast) } + /// Find a AstNode by offset inside SyntaxNode, if it is inside *MacroCall*, + /// descend it and find again + pub fn find_node_at_offset_with_descend( + &self, + node: &SyntaxNode, + offset: TextUnit, + ) -> Option { + if let Some(it) = find_node_at_offset(&node, offset) { + return Some(it); + } + self.descend_node_at_offset(&node, offset) + } + pub fn type_of_expr(&self, expr: &ast::Expr) -> Option { self.analyze(expr.syntax()).type_of(self.db, &expr) } -- cgit v1.2.3 From f647faac60660d9022b9d677c894d65e98c8ae5f Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sun, 22 Mar 2020 19:52:45 +0800 Subject: Refactor search --- crates/ra_ide_db/src/search.rs | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) (limited to 'crates') diff --git a/crates/ra_ide_db/src/search.rs b/crates/ra_ide_db/src/search.rs index cf78d3e41..117454695 100644 --- a/crates/ra_ide_db/src/search.rs +++ b/crates/ra_ide_db/src/search.rs @@ -10,9 +10,7 @@ use hir::{DefWithBody, HasSource, ModuleSource, Semantics}; use once_cell::unsync::Lazy; use ra_db::{FileId, FileRange, SourceDatabaseExt}; use ra_prof::profile; -use ra_syntax::{ - algo::find_node_at_offset, ast, match_ast, AstNode, TextRange, TextUnit, TokenAtOffset, -}; +use ra_syntax::{ast, match_ast, AstNode, TextRange, TextUnit}; use rustc_hash::FxHashMap; use test_utils::tested_by; @@ -219,21 +217,11 @@ impl Definition { continue; } - let name_ref = - if let Some(name_ref) = find_node_at_offset::(&tree, offset) { + let name_ref: ast::NameRef = + if let Some(name_ref) = sema.find_node_at_offset_with_descend(&tree, offset) { name_ref } else { - // Handle macro token cases - let token = match tree.token_at_offset(offset) { - TokenAtOffset::None => continue, - TokenAtOffset::Single(t) => t, - TokenAtOffset::Between(_, t) => t, - }; - let expanded = sema.descend_into_macros(token); - match ast::NameRef::cast(expanded.parent()) { - Some(name_ref) => name_ref, - _ => continue, - } + continue; }; // FIXME: reuse sb -- cgit v1.2.3 From cba4dd1a8ac8e0dcd8a82efc1a490e4676340388 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sun, 22 Mar 2020 19:53:28 +0800 Subject: Improve find_all_ref work inside macro --- crates/ra_ide/src/references.rs | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) (limited to 'crates') diff --git a/crates/ra_ide/src/references.rs b/crates/ra_ide/src/references.rs index 3ea0ac230..746cc86ba 100644 --- a/crates/ra_ide/src/references.rs +++ b/crates/ra_ide/src/references.rs @@ -94,12 +94,16 @@ pub(crate) fn find_all_refs( let sema = Semantics::new(db); let syntax = sema.parse(position.file_id).syntax().clone(); - let (opt_name, search_kind) = - if let Some(name) = get_struct_def_name_for_struct_literal_search(&syntax, position) { - (Some(name), ReferenceKind::StructLiteral) - } else { - (find_node_at_offset::(&syntax, position.offset), ReferenceKind::Other) - }; + let (opt_name, search_kind) = if let Some(name) = + get_struct_def_name_for_struct_literal_search(&sema, &syntax, position) + { + (Some(name), ReferenceKind::StructLiteral) + } else { + ( + sema.find_node_at_offset_with_descend::(&syntax, position.offset), + ReferenceKind::Other, + ) + }; let RangeInfo { range, info: def } = find_name(&sema, &syntax, position, opt_name)?; @@ -131,7 +135,8 @@ fn find_name( let range = name.syntax().text_range(); return Some(RangeInfo::new(range, def)); } - let name_ref = find_node_at_offset::(&syntax, position.offset)?; + let name_ref = + sema.find_node_at_offset_with_descend::(&syntax, position.offset)?; let def = classify_name_ref(sema, &name_ref)?.definition(); let range = name_ref.syntax().text_range(); Some(RangeInfo::new(range, def)) @@ -157,6 +162,7 @@ fn decl_access(def: &Definition, syntax: &SyntaxNode, range: TextRange) -> Optio } fn get_struct_def_name_for_struct_literal_search( + sema: &Semantics, syntax: &SyntaxNode, position: FilePosition, ) -> Option { @@ -164,10 +170,18 @@ fn get_struct_def_name_for_struct_literal_search( if right.kind() != SyntaxKind::L_CURLY && right.kind() != SyntaxKind::L_PAREN { return None; } - if let Some(name) = find_node_at_offset::(&syntax, left.text_range().start()) { + if let Some(name) = + sema.find_node_at_offset_with_descend::(&syntax, left.text_range().start()) + { return name.syntax().ancestors().find_map(ast::StructDef::cast).and_then(|l| l.name()); } - if find_node_at_offset::(&syntax, left.text_range().start()).is_some() { + if sema + .find_node_at_offset_with_descend::( + &syntax, + left.text_range().start(), + ) + .is_some() + { return left.ancestors().find_map(ast::StructDef::cast).and_then(|l| l.name()); } } -- cgit v1.2.3 From 6d5443ef945c415f21ced1594003e8e6eed5e44a Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sun, 22 Mar 2020 19:53:34 +0800 Subject: Add test --- crates/ra_ide/src/references/rename.rs | 57 ++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'crates') diff --git a/crates/ra_ide/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs index 7d1190af9..9acc6158a 100644 --- a/crates/ra_ide/src/references/rename.rs +++ b/crates/ra_ide/src/references/rename.rs @@ -249,6 +249,63 @@ mod tests { ); } + #[test] + fn test_rename_for_macro_args_rev() { + test_rename( + r#" + macro_rules! foo {($i:ident) => {$i} } + fn main() { + let a = "test"; + foo!(a<|>); + }"#, + "b", + r#" + macro_rules! foo {($i:ident) => {$i} } + fn main() { + let b = "test"; + foo!(b); + }"#, + ); + } + + #[test] + fn test_rename_for_macro_define_fn() { + test_rename( + r#" + macro_rules! define_fn {($id:ident) => { fn $id{} }} + define_fn!(foo); + fn main() { + fo<|>o(); + }"#, + "bar", + r#" + macro_rules! define_fn {($id:ident) => { fn $id{} }} + define_fn!(bar); + fn main() { + bar(); + }"#, + ); + } + + #[test] + fn test_rename_for_macro_define_fn_rev() { + test_rename( + r#" + macro_rules! define_fn {($id:ident) => { fn $id{} }} + define_fn!(fo<|>o); + fn main() { + foo(); + }"#, + "bar", + r#" + macro_rules! define_fn {($id:ident) => { fn $id{} }} + define_fn!(bar); + fn main() { + bar(); + }"#, + ); + } + #[test] fn test_rename_for_param_inside() { test_rename( -- cgit v1.2.3 From af8c37cb57fcde849ef333100b8057c427bfa9a9 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sun, 22 Mar 2020 22:01:48 +0800 Subject: Fix typo Co-Authored-By: Veetaha --- crates/ra_hir/src/semantics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates') diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs index caece91c1..d982f6ffa 100644 --- a/crates/ra_hir/src/semantics.rs +++ b/crates/ra_hir/src/semantics.rs @@ -142,7 +142,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { } /// Find a AstNode by offset inside SyntaxNode, if it is inside *Macrofile*, - /// search up until it is target AstNode type + /// search up until it is of the target AstNode type pub fn find_node_at_offset_with_macros( &self, node: &SyntaxNode, -- cgit v1.2.3