From 8198e13c26fe985af5893af7bdac04041880b461 Mon Sep 17 00:00:00 2001 From: Lenard Pratt Date: Wed, 24 Apr 2019 21:16:50 +0100 Subject: Added local macro goto --- .../ra_ide_api/src/completion/completion_item.rs | 1 + crates/ra_ide_api/src/display/navigation_target.rs | 10 ++++++ crates/ra_ide_api/src/goto_definition.rs | 40 ++++++++++++++++++++++ crates/ra_ide_api/src/marks.rs | 1 + 4 files changed, 52 insertions(+) (limited to 'crates/ra_ide_api/src') diff --git a/crates/ra_ide_api/src/completion/completion_item.rs b/crates/ra_ide_api/src/completion/completion_item.rs index f515fcc14..6f1392231 100644 --- a/crates/ra_ide_api/src/completion/completion_item.rs +++ b/crates/ra_ide_api/src/completion/completion_item.rs @@ -89,6 +89,7 @@ pub enum CompletionItemKind { TypeAlias, Method, TypeParam, + Macro, } #[derive(Debug, PartialEq, Eq, Copy, Clone)] diff --git a/crates/ra_ide_api/src/display/navigation_target.rs b/crates/ra_ide_api/src/display/navigation_target.rs index 84645287d..765cf883b 100644 --- a/crates/ra_ide_api/src/display/navigation_target.rs +++ b/crates/ra_ide_api/src/display/navigation_target.rs @@ -213,6 +213,15 @@ impl NavigationTarget { } } + pub(crate) fn from_macro_def( + db: &RootDatabase, + macro_call: hir::MacroByExampleDef, + ) -> NavigationTarget { + let (file_id, node) = macro_call.source(db); + log::debug!("nav target {}", node.syntax().debug_dump()); + NavigationTarget::from_named(file_id.original_file(db), &*node) + } + #[cfg(test)] pub(crate) fn assert_match(&self, expected: &str) { let actual = self.debug_render(); @@ -289,6 +298,7 @@ impl NavigationTarget { .visit(doc_comments::) .visit(doc_comments::) .visit(doc_comments::) + .visit(doc_comments::) .accept(&node)? } diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index 163781f88..533c229fe 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs @@ -59,6 +59,21 @@ pub(crate) fn reference_definition( return Exact(NavigationTarget::from_function(db, func)); } } + + //it could be a macro call + if let Some(macro_call) = name_ref + .syntax() + .parent() + .and_then(|node| node.parent()) + .and_then(|node| node.parent()) + .and_then(ast::MacroCall::cast) + { + tested_by!(goto_definition_works_for_macros); + if let Some(macro_call) = analyzer.resolve_macro_call(db, file_id, macro_call) { + return Exact(NavigationTarget::from_macro_def(db, macro_call)); + } + } + // It could also be a field access if let Some(field_expr) = name_ref.syntax().parent().and_then(ast::FieldExpr::cast) { tested_by!(goto_definition_works_for_fields); @@ -97,6 +112,10 @@ pub(crate) fn reference_definition( hir::PathResolution::GenericParam(..) => { // FIXME: go to the generic param def } + hir::PathResolution::Macro(def) => { + let nav = NavigationTarget::from_macro_def(db, def); + return Exact(nav); + } hir::PathResolution::SelfType(impl_block) => { let ty = impl_block.target_ty(db); @@ -156,6 +175,7 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option .visit(|node: &ast::TraitDef| NavigationTarget::from_named(file_id, node)) .visit(|node: &ast::NamedFieldDef| NavigationTarget::from_named(file_id, node)) .visit(|node: &ast::Module| NavigationTarget::from_named(file_id, node)) + .visit(|node: &ast::MacroCall| NavigationTarget::from_named(file_id, node)) .accept(node) } @@ -227,6 +247,26 @@ mod tests { ); } + #[test] + fn goto_definition_works_for_macros() { + covers!(goto_definition_works_for_macros); + check_goto( + " + //- /lib.rs + macro_rules! foo { + () => { + {} + }; + } + + fn bar() { + <|>foo!(); + } + ", + "foo MACRO_CALL FileId(1) [0; 50) [13; 16)", + ); + } + #[test] fn goto_definition_works_for_methods() { covers!(goto_definition_works_for_methods); diff --git a/crates/ra_ide_api/src/marks.rs b/crates/ra_ide_api/src/marks.rs index bcbe0d21b..cc894a7df 100644 --- a/crates/ra_ide_api/src/marks.rs +++ b/crates/ra_ide_api/src/marks.rs @@ -1,5 +1,6 @@ test_utils::marks!( inserts_parens_for_function_calls + goto_definition_works_for_macros goto_definition_works_for_methods goto_definition_works_for_fields goto_definition_works_for_named_fields -- cgit v1.2.3