From e8741b9d75eb4edd711c6516c3b17c87c0431166 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Mon, 4 Nov 2019 01:49:41 +0800 Subject: Use new expansion feature in goto_definition --- crates/ra_ide_api/src/display/navigation_target.rs | 122 +++++++++++++++------ crates/ra_ide_api/src/goto_definition.rs | 37 ++++--- 2 files changed, 114 insertions(+), 45 deletions(-) (limited to 'crates/ra_ide_api') diff --git a/crates/ra_ide_api/src/display/navigation_target.rs b/crates/ra_ide_api/src/display/navigation_target.rs index 5cb67fb95..0c3e25ce6 100644 --- a/crates/ra_ide_api/src/display/navigation_target.rs +++ b/crates/ra_ide_api/src/display/navigation_target.rs @@ -29,6 +29,20 @@ pub struct NavigationTarget { docs: Option, } +fn find_range_from_node( + db: &RootDatabase, + src: hir::HirFileId, + node: &SyntaxNode, +) -> (FileId, TextRange) { + let text_range = node.text_range(); + let (file_id, text_range) = src + .parent_expansion(db) + .and_then(|(files, expansion_info)| expansion_info.find_range(text_range, files)) + .unwrap_or((src, text_range)); + + (file_id.original_file(db), text_range) +} + impl NavigationTarget { /// When `focus_range` is specified, returns it. otherwise /// returns `full_range` @@ -72,8 +86,12 @@ impl NavigationTarget { self.focus_range } - pub(crate) fn from_bind_pat(file_id: FileId, pat: &ast::BindPat) -> NavigationTarget { - NavigationTarget::from_named(file_id, pat, None, None) + pub(crate) fn from_bind_pat( + db: &RootDatabase, + file_id: FileId, + pat: &ast::BindPat, + ) -> NavigationTarget { + NavigationTarget::from_named(db, file_id.into(), pat, None, None) } pub(crate) fn from_symbol(db: &RootDatabase, symbol: FileSymbol) -> NavigationTarget { @@ -96,7 +114,7 @@ impl NavigationTarget { ) -> NavigationTarget { let parse = db.parse(file_id); let pat = pat.to_node(parse.tree().syntax()); - NavigationTarget::from_bind_pat(file_id, &pat) + NavigationTarget::from_bind_pat(db, file_id, &pat) } pub(crate) fn from_self_param( @@ -119,31 +137,47 @@ impl NavigationTarget { pub(crate) fn from_module(db: &RootDatabase, module: hir::Module) -> NavigationTarget { let src = module.definition_source(db); - let file_id = src.file_id.original_file(db); let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default(); + match src.ast { ModuleSource::SourceFile(node) => { - NavigationTarget::from_syntax(file_id, name, None, node.syntax(), None, None) + let (file_id, text_range) = find_range_from_node(db, src.file_id, node.syntax()); + + NavigationTarget::from_syntax( + file_id, + name, + None, + text_range, + node.syntax(), + None, + None, + ) + } + ModuleSource::Module(node) => { + let (file_id, text_range) = find_range_from_node(db, src.file_id, node.syntax()); + + NavigationTarget::from_syntax( + file_id, + name, + None, + text_range, + node.syntax(), + node.doc_comment_text(), + node.short_label(), + ) } - ModuleSource::Module(node) => NavigationTarget::from_syntax( - file_id, - name, - None, - node.syntax(), - node.doc_comment_text(), - node.short_label(), - ), } } pub(crate) fn from_module_to_decl(db: &RootDatabase, module: hir::Module) -> NavigationTarget { let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default(); if let Some(src) = module.declaration_source(db) { - let file_id = src.file_id.original_file(db); + let (file_id, text_range) = find_range_from_node(db, src.file_id, src.ast.syntax()); return NavigationTarget::from_syntax( file_id, name, None, + text_range, src.ast.syntax(), src.ast.doc_comment_text(), src.ast.short_label(), @@ -154,13 +188,25 @@ impl NavigationTarget { pub(crate) fn from_field(db: &RootDatabase, field: hir::StructField) -> NavigationTarget { let src = field.source(db); - let file_id = src.file_id.original_file(db); match src.ast { - FieldSource::Named(it) => { - NavigationTarget::from_named(file_id, &it, it.doc_comment_text(), it.short_label()) - } + FieldSource::Named(it) => NavigationTarget::from_named( + db, + src.file_id, + &it, + it.doc_comment_text(), + it.short_label(), + ), FieldSource::Pos(it) => { - NavigationTarget::from_syntax(file_id, "".into(), None, it.syntax(), None, None) + let (file_id, text_range) = find_range_from_node(db, src.file_id, it.syntax()); + NavigationTarget::from_syntax( + file_id, + "".into(), + None, + text_range, + it.syntax(), + None, + None, + ) } } } @@ -172,7 +218,8 @@ impl NavigationTarget { { let src = def.source(db); NavigationTarget::from_named( - src.file_id.original_file(db), + db, + src.file_id, &src.ast, src.ast.doc_comment_text(), src.ast.short_label(), @@ -212,10 +259,13 @@ impl NavigationTarget { impl_block: hir::ImplBlock, ) -> NavigationTarget { let src = impl_block.source(db); + let (file_id, text_range) = find_range_from_node(db, src.file_id, src.ast.syntax()); + NavigationTarget::from_syntax( - src.file_id.original_file(db), + file_id, "impl".into(), None, + text_range, src.ast.syntax(), None, None, @@ -236,12 +286,7 @@ impl NavigationTarget { pub(crate) fn from_macro_def(db: &RootDatabase, macro_call: hir::MacroDef) -> NavigationTarget { let src = macro_call.source(db); log::debug!("nav target {:#?}", src.ast.syntax()); - NavigationTarget::from_named( - src.file_id.original_file(db), - &src.ast, - src.ast.doc_comment_text(), - None, - ) + NavigationTarget::from_named(db, src.file_id, &src.ast, src.ast.doc_comment_text(), None) } #[cfg(test)] @@ -270,21 +315,35 @@ impl NavigationTarget { /// Allows `NavigationTarget` to be created from a `NameOwner` pub(crate) fn from_named( - file_id: FileId, + db: &RootDatabase, + file_id: hir::HirFileId, node: &impl ast::NameOwner, docs: Option, description: Option, ) -> NavigationTarget { //FIXME: use `_` instead of empty string let name = node.name().map(|it| it.text().clone()).unwrap_or_default(); - let focus_range = node.name().map(|it| it.syntax().text_range()); - NavigationTarget::from_syntax(file_id, name, focus_range, node.syntax(), docs, description) + + let focus_range = node.name().map(|it| find_range_from_node(db, file_id, it.syntax()).1); + + let (file_id, full_range) = find_range_from_node(db, file_id, node.syntax()); + + NavigationTarget::from_syntax( + file_id, + name, + focus_range, + full_range, + node.syntax(), + docs, + description, + ) } fn from_syntax( file_id: FileId, name: SmolStr, focus_range: Option, + full_range: TextRange, node: &SyntaxNode, docs: Option, description: Option, @@ -293,9 +352,8 @@ impl NavigationTarget { file_id, name, kind: node.kind(), - full_range: node.text_range(), + full_range, focus_range, - // ptr: Some(LocalSyntaxPtr::new(node)), container_name: None, description, docs, diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index c1ce54bea..97127706f 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs @@ -101,19 +101,20 @@ pub(crate) fn name_definition( } } - if let Some(nav) = named_target(file_id, &parent) { + if let Some(nav) = named_target(db, file_id, &parent) { return Some(vec![nav]); } None } -fn named_target(file_id: FileId, node: &SyntaxNode) -> Option { +fn named_target(db: &RootDatabase, file_id: FileId, node: &SyntaxNode) -> Option { match_ast! { match node { ast::StructDef(it) => { Some(NavigationTarget::from_named( - file_id, + db, + file_id.into(), &it, it.doc_comment_text(), it.short_label(), @@ -121,7 +122,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option }, ast::EnumDef(it) => { Some(NavigationTarget::from_named( - file_id, + db, + file_id.into(), &it, it.doc_comment_text(), it.short_label(), @@ -129,7 +131,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option }, ast::EnumVariant(it) => { Some(NavigationTarget::from_named( - file_id, + db, + file_id.into(), &it, it.doc_comment_text(), it.short_label(), @@ -137,7 +140,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option }, ast::FnDef(it) => { Some(NavigationTarget::from_named( - file_id, + db, + file_id.into(), &it, it.doc_comment_text(), it.short_label(), @@ -145,7 +149,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option }, ast::TypeAliasDef(it) => { Some(NavigationTarget::from_named( - file_id, + db, + file_id.into(), &it, it.doc_comment_text(), it.short_label(), @@ -153,7 +158,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option }, ast::ConstDef(it) => { Some(NavigationTarget::from_named( - file_id, + db, + file_id.into(), &it, it.doc_comment_text(), it.short_label(), @@ -161,7 +167,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option }, ast::StaticDef(it) => { Some(NavigationTarget::from_named( - file_id, + db, + file_id.into(), &it, it.doc_comment_text(), it.short_label(), @@ -169,7 +176,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option }, ast::TraitDef(it) => { Some(NavigationTarget::from_named( - file_id, + db, + file_id.into(), &it, it.doc_comment_text(), it.short_label(), @@ -177,7 +185,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option }, ast::RecordFieldDef(it) => { Some(NavigationTarget::from_named( - file_id, + db, + file_id.into(), &it, it.doc_comment_text(), it.short_label(), @@ -185,7 +194,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option }, ast::Module(it) => { Some(NavigationTarget::from_named( - file_id, + db, + file_id.into(), &it, it.doc_comment_text(), it.short_label(), @@ -193,7 +203,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option }, ast::MacroCall(it) => { Some(NavigationTarget::from_named( - file_id, + db, + file_id.into(), &it, it.doc_comment_text(), None, -- cgit v1.2.3 From 1630a34c3f5c8b1ae2b4e1a99a918fd4d4ec52aa Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Mon, 4 Nov 2019 01:49:49 +0800 Subject: Add tests --- crates/ra_ide_api/src/goto_definition.rs | 40 ++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'crates/ra_ide_api') diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index 97127706f..afa59cbe3 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs @@ -345,6 +345,46 @@ mod tests { ); } + #[test] + fn goto_definition_works_for_macro_defined_fn_with_arg() { + check_goto( + " + //- /lib.rs + macro_rules! define_fn { + ($name:ident) => (fn $name() {}) + } + + define_fn!( + foo + ) + + fn bar() { + <|>foo(); + } + ", + "foo FN_DEF FileId(1) [80; 83) [80; 83)", + ); + } + + #[test] + fn goto_definition_works_for_macro_defined_fn_no_arg() { + check_goto( + " + //- /lib.rs + macro_rules! define_fn { + () => (fn foo() {}) + } + + define_fn!(); + + fn bar() { + <|>foo(); + } + ", + "foo FN_DEF FileId(1) [39; 42) [39; 42)", + ); + } + #[test] fn goto_definition_works_for_methods() { covers!(goto_definition_works_for_methods); -- cgit v1.2.3 From d8b7ba201e005e533d132f4942ad611468f21a28 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Mon, 4 Nov 2019 01:56:38 +0800 Subject: Add note for recurseive macro generated code --- crates/ra_ide_api/src/display/navigation_target.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'crates/ra_ide_api') diff --git a/crates/ra_ide_api/src/display/navigation_target.rs b/crates/ra_ide_api/src/display/navigation_target.rs index 0c3e25ce6..b9e3132f4 100644 --- a/crates/ra_ide_api/src/display/navigation_target.rs +++ b/crates/ra_ide_api/src/display/navigation_target.rs @@ -40,6 +40,7 @@ fn find_range_from_node( .and_then(|(files, expansion_info)| expansion_info.find_range(text_range, files)) .unwrap_or((src, text_range)); + // FIXME: handle recursive macro generated macro (file_id.original_file(db), text_range) } -- cgit v1.2.3 From d01e0abdb57c5be340934cb51e2f6b1a2e6c0373 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sat, 9 Nov 2019 04:00:27 +0800 Subject: Refactor and simpfily --- crates/ra_ide_api/src/display/navigation_target.rs | 5 +---- crates/ra_ide_api/src/status.rs | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'crates/ra_ide_api') diff --git a/crates/ra_ide_api/src/display/navigation_target.rs b/crates/ra_ide_api/src/display/navigation_target.rs index b9e3132f4..b77e19231 100644 --- a/crates/ra_ide_api/src/display/navigation_target.rs +++ b/crates/ra_ide_api/src/display/navigation_target.rs @@ -37,7 +37,7 @@ fn find_range_from_node( let text_range = node.text_range(); let (file_id, text_range) = src .parent_expansion(db) - .and_then(|(files, expansion_info)| expansion_info.find_range(text_range, files)) + .and_then(|expansion_info| expansion_info.find_range(text_range)) .unwrap_or((src, text_range)); // FIXME: handle recursive macro generated macro @@ -139,7 +139,6 @@ impl NavigationTarget { pub(crate) fn from_module(db: &RootDatabase, module: hir::Module) -> NavigationTarget { let src = module.definition_source(db); let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default(); - match src.ast { ModuleSource::SourceFile(node) => { let (file_id, text_range) = find_range_from_node(db, src.file_id, node.syntax()); @@ -324,9 +323,7 @@ impl NavigationTarget { ) -> NavigationTarget { //FIXME: use `_` instead of empty string let name = node.name().map(|it| it.text().clone()).unwrap_or_default(); - let focus_range = node.name().map(|it| find_range_from_node(db, file_id, it.syntax()).1); - let (file_id, full_range) = find_range_from_node(db, file_id, node.syntax()); NavigationTarget::from_syntax( diff --git a/crates/ra_ide_api/src/status.rs b/crates/ra_ide_api/src/status.rs index f91f16c8e..1bb27eb85 100644 --- a/crates/ra_ide_api/src/status.rs +++ b/crates/ra_ide_api/src/status.rs @@ -94,10 +94,10 @@ impl FromIterator>> for SyntaxTreeStat } } -impl FromIterator>>> for SyntaxTreeStats { +impl FromIterator, M)>>> for SyntaxTreeStats { fn from_iter(iter: T) -> SyntaxTreeStats where - T: IntoIterator>>>, + T: IntoIterator, M)>>>, { let mut res = SyntaxTreeStats::default(); for entry in iter { -- cgit v1.2.3 From 0a5ec69404a2556dd82e5bb00b295aebaa291f04 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sat, 9 Nov 2019 12:00:46 +0800 Subject: Remove map_ranges in RevTokenMap --- crates/ra_ide_api/src/display/navigation_target.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/ra_ide_api') diff --git a/crates/ra_ide_api/src/display/navigation_target.rs b/crates/ra_ide_api/src/display/navigation_target.rs index b77e19231..1bf81e7d5 100644 --- a/crates/ra_ide_api/src/display/navigation_target.rs +++ b/crates/ra_ide_api/src/display/navigation_target.rs @@ -36,7 +36,7 @@ fn find_range_from_node( ) -> (FileId, TextRange) { let text_range = node.text_range(); let (file_id, text_range) = src - .parent_expansion(db) + .expansion_info(db) .and_then(|expansion_info| expansion_info.find_range(text_range)) .unwrap_or((src, text_range)); -- cgit v1.2.3