diff options
Diffstat (limited to 'crates/ra_ide_api/src/goto_definition.rs')
-rw-r--r-- | crates/ra_ide_api/src/goto_definition.rs | 40 |
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( |