diff options
-rw-r--r-- | crates/ra_hir/src/expr.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres.rs | 18 | ||||
-rw-r--r-- | crates/ra_hir/src/resolve.rs | 10 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 9 | ||||
-rw-r--r-- | crates/ra_ide_api/src/goto_definition.rs | 23 | ||||
-rw-r--r-- | crates/ra_ide_api/src/name_ref_kind.rs | 2 |
6 files changed, 55 insertions, 9 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 9618236e5..51913d37b 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -828,7 +828,7 @@ where | |||
828 | .ast_id(e) | 828 | .ast_id(e) |
829 | .with_file_id(self.current_file_id); | 829 | .with_file_id(self.current_file_id); |
830 | 830 | ||
831 | if let Some(def) = self.resolver.resolve_macro_call(path) { | 831 | if let Some(def) = self.resolver.resolve_macro_call(self.db, path) { |
832 | let call_id = MacroCallLoc { def, ast_id }.id(self.db); | 832 | let call_id = MacroCallLoc { def, ast_id }.id(self.db); |
833 | let file_id = call_id.as_file(MacroFileKind::Expr); | 833 | let file_id = call_id.as_file(MacroFileKind::Expr); |
834 | if let Some(node) = self.db.parse_or_expand(file_id) { | 834 | if let Some(node) = self.db.parse_or_expand(file_id) { |
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index aa26345b2..6b1160aa7 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs | |||
@@ -320,8 +320,22 @@ impl CrateDefMap { | |||
320 | (res.resolved_def, res.segment_index) | 320 | (res.resolved_def, res.segment_index) |
321 | } | 321 | } |
322 | 322 | ||
323 | pub(crate) fn find_macro(&self, name: &Name) -> Option<MacroDefId> { | 323 | pub(crate) fn find_macro( |
324 | self.public_macros.get(name).or(self.local_macros.get(name)).map(|it| *it) | 324 | &self, |
325 | db: &impl DefDatabase, | ||
326 | original_module: CrateModuleId, | ||
327 | path: &Path, | ||
328 | ) -> Option<MacroDefId> { | ||
329 | let name = path.expand_macro_expr()?; | ||
330 | // search local first | ||
331 | // FIXME: Remove public_macros check when we have a correct local_macors implementation | ||
332 | let local = self.public_macros.get(&name).or(self.local_macros.get(&name)).map(|it| *it); | ||
333 | if local.is_some() { | ||
334 | return local; | ||
335 | } | ||
336 | |||
337 | let res = self.resolve_path_fp_with_macro(db, ResolveMode::Other, original_module, path); | ||
338 | res.resolved_def.right().map(|m| m.id) | ||
325 | } | 339 | } |
326 | 340 | ||
327 | // Returns Yes if we are sure that additions to `ItemMap` wouldn't change | 341 | // Returns Yes if we are sure that additions to `ItemMap` wouldn't change |
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index fedfe2fee..0f6ee7f47 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs | |||
@@ -130,9 +130,13 @@ impl Resolver { | |||
130 | resolution | 130 | resolution |
131 | } | 131 | } |
132 | 132 | ||
133 | pub(crate) fn resolve_macro_call(&self, path: Option<Path>) -> Option<MacroDefId> { | 133 | pub(crate) fn resolve_macro_call( |
134 | let name = path.and_then(|path| path.expand_macro_expr()).unwrap_or_else(Name::missing); | 134 | &self, |
135 | self.module()?.0.find_macro(&name) | 135 | db: &impl HirDatabase, |
136 | path: Option<Path>, | ||
137 | ) -> Option<MacroDefId> { | ||
138 | let m = self.module()?; | ||
139 | m.0.find_macro(db, m.1, &path?) | ||
136 | } | 140 | } |
137 | 141 | ||
138 | /// Returns the resolved path segments | 142 | /// Returns the resolved path segments |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 860e10069..75ed2de6c 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -283,8 +283,13 @@ impl SourceAnalyzer { | |||
283 | self.infer.as_ref()?.field_resolution(expr_id) | 283 | self.infer.as_ref()?.field_resolution(expr_id) |
284 | } | 284 | } |
285 | 285 | ||
286 | pub fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option<MacroByExampleDef> { | 286 | pub fn resolve_macro_call( |
287 | let id = self.resolver.resolve_macro_call(macro_call.path().and_then(Path::from_ast))?; | 287 | &self, |
288 | db: &impl HirDatabase, | ||
289 | macro_call: &ast::MacroCall, | ||
290 | ) -> Option<MacroByExampleDef> { | ||
291 | let id = | ||
292 | self.resolver.resolve_macro_call(db, macro_call.path().and_then(Path::from_ast))?; | ||
288 | Some(MacroByExampleDef { id }) | 293 | Some(MacroByExampleDef { id }) |
289 | } | 294 | } |
290 | 295 | ||
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index 97b367115..e72b7a6e7 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs | |||
@@ -217,6 +217,29 @@ mod tests { | |||
217 | } | 217 | } |
218 | 218 | ||
219 | #[test] | 219 | #[test] |
220 | fn goto_definition_works_for_macros_from_other_crates() { | ||
221 | covers!(goto_definition_works_for_macros); | ||
222 | check_goto( | ||
223 | " | ||
224 | //- /lib.rs | ||
225 | use foo::foo; | ||
226 | fn bar() { | ||
227 | <|>foo!(); | ||
228 | } | ||
229 | |||
230 | //- /foo/lib.rs | ||
231 | #[macro_export] | ||
232 | macro_rules! foo { | ||
233 | () => { | ||
234 | {} | ||
235 | }; | ||
236 | } | ||
237 | ", | ||
238 | "foo MACRO_CALL FileId(2) [0; 79) [29; 32)", | ||
239 | ); | ||
240 | } | ||
241 | |||
242 | #[test] | ||
220 | fn goto_definition_works_for_methods() { | 243 | fn goto_definition_works_for_methods() { |
221 | covers!(goto_definition_works_for_methods); | 244 | covers!(goto_definition_works_for_methods); |
222 | check_goto( | 245 | check_goto( |
diff --git a/crates/ra_ide_api/src/name_ref_kind.rs b/crates/ra_ide_api/src/name_ref_kind.rs index b498fe495..90972bc58 100644 --- a/crates/ra_ide_api/src/name_ref_kind.rs +++ b/crates/ra_ide_api/src/name_ref_kind.rs | |||
@@ -39,7 +39,7 @@ pub(crate) fn classify_name_ref( | |||
39 | .and_then(ast::MacroCall::cast) | 39 | .and_then(ast::MacroCall::cast) |
40 | { | 40 | { |
41 | tested_by!(goto_definition_works_for_macros); | 41 | tested_by!(goto_definition_works_for_macros); |
42 | if let Some(mac) = analyzer.resolve_macro_call(macro_call) { | 42 | if let Some(mac) = analyzer.resolve_macro_call(db, macro_call) { |
43 | return Some(Macro(mac)); | 43 | return Some(Macro(mac)); |
44 | } | 44 | } |
45 | } | 45 | } |