aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/goto_definition.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api/src/goto_definition.rs')
-rw-r--r--crates/ra_ide_api/src/goto_definition.rs40
1 files changed, 40 insertions, 0 deletions
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(
59 return Exact(NavigationTarget::from_function(db, func)); 59 return Exact(NavigationTarget::from_function(db, func));
60 } 60 }
61 } 61 }
62
63 //it could be a macro call
64 if let Some(macro_call) = name_ref
65 .syntax()
66 .parent()
67 .and_then(|node| node.parent())
68 .and_then(|node| node.parent())
69 .and_then(ast::MacroCall::cast)
70 {
71 tested_by!(goto_definition_works_for_macros);
72 if let Some(macro_call) = analyzer.resolve_macro_call(db, file_id, macro_call) {
73 return Exact(NavigationTarget::from_macro_def(db, macro_call));
74 }
75 }
76
62 // It could also be a field access 77 // It could also be a field access
63 if let Some(field_expr) = name_ref.syntax().parent().and_then(ast::FieldExpr::cast) { 78 if let Some(field_expr) = name_ref.syntax().parent().and_then(ast::FieldExpr::cast) {
64 tested_by!(goto_definition_works_for_fields); 79 tested_by!(goto_definition_works_for_fields);
@@ -97,6 +112,10 @@ pub(crate) fn reference_definition(
97 hir::PathResolution::GenericParam(..) => { 112 hir::PathResolution::GenericParam(..) => {
98 // FIXME: go to the generic param def 113 // FIXME: go to the generic param def
99 } 114 }
115 hir::PathResolution::Macro(def) => {
116 let nav = NavigationTarget::from_macro_def(db, def);
117 return Exact(nav);
118 }
100 hir::PathResolution::SelfType(impl_block) => { 119 hir::PathResolution::SelfType(impl_block) => {
101 let ty = impl_block.target_ty(db); 120 let ty = impl_block.target_ty(db);
102 121
@@ -156,6 +175,7 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
156 .visit(|node: &ast::TraitDef| NavigationTarget::from_named(file_id, node)) 175 .visit(|node: &ast::TraitDef| NavigationTarget::from_named(file_id, node))
157 .visit(|node: &ast::NamedFieldDef| NavigationTarget::from_named(file_id, node)) 176 .visit(|node: &ast::NamedFieldDef| NavigationTarget::from_named(file_id, node))
158 .visit(|node: &ast::Module| NavigationTarget::from_named(file_id, node)) 177 .visit(|node: &ast::Module| NavigationTarget::from_named(file_id, node))
178 .visit(|node: &ast::MacroCall| NavigationTarget::from_named(file_id, node))
159 .accept(node) 179 .accept(node)
160} 180}
161 181
@@ -228,6 +248,26 @@ mod tests {
228 } 248 }
229 249
230 #[test] 250 #[test]
251 fn goto_definition_works_for_macros() {
252 covers!(goto_definition_works_for_macros);
253 check_goto(
254 "
255 //- /lib.rs
256 macro_rules! foo {
257 () => {
258 {}
259 };
260 }
261
262 fn bar() {
263 <|>foo!();
264 }
265 ",
266 "foo MACRO_CALL FileId(1) [0; 50) [13; 16)",
267 );
268 }
269
270 #[test]
231 fn goto_definition_works_for_methods() { 271 fn goto_definition_works_for_methods() {
232 covers!(goto_definition_works_for_methods); 272 covers!(goto_definition_works_for_methods);
233 check_goto( 273 check_goto(