From 371961be0e0b0741599ebf3d9435c03fd45cf777 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sat, 1 Jun 2019 19:34:19 +0800 Subject: [PATCH] Improve goto definition for MBE --- crates/ra_hir/src/expr.rs | 2 +- crates/ra_hir/src/nameres.rs | 18 ++++++++++++++++-- crates/ra_hir/src/resolve.rs | 10 +++++++--- crates/ra_hir/src/source_binder.rs | 9 +++++++-- crates/ra_ide_api/src/goto_definition.rs | 23 +++++++++++++++++++++++ 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 9618236e51..51913d37bd 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -828,7 +828,7 @@ where .ast_id(e) .with_file_id(self.current_file_id); - if let Some(def) = self.resolver.resolve_macro_call(path) { + if let Some(def) = self.resolver.resolve_macro_call(self.db, path) { let call_id = MacroCallLoc { def, ast_id }.id(self.db); let file_id = call_id.as_file(MacroFileKind::Expr); 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 aa26345b22..6b1160aa7f 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs @@ -320,8 +320,22 @@ impl CrateDefMap { (res.resolved_def, res.segment_index) } - pub(crate) fn find_macro(&self, name: &Name) -> Option { - self.public_macros.get(name).or(self.local_macros.get(name)).map(|it| *it) + pub(crate) fn find_macro( + &self, + db: &impl DefDatabase, + original_module: CrateModuleId, + path: &Path, + ) -> Option { + let name = path.expand_macro_expr()?; + // search local first + // FIXME: Remove public_macros check when we have a correct local_macors implementation + let local = self.public_macros.get(&name).or(self.local_macros.get(&name)).map(|it| *it); + if local.is_some() { + return local; + } + + let res = self.resolve_path_fp_with_macro(db, ResolveMode::Other, original_module, path); + res.resolved_def.right().map(|m| m.id) } // 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 fedfe2feeb..0f6ee7f470 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs @@ -130,9 +130,13 @@ impl Resolver { resolution } - pub(crate) fn resolve_macro_call(&self, path: Option) -> Option { - let name = path.and_then(|path| path.expand_macro_expr()).unwrap_or_else(Name::missing); - self.module()?.0.find_macro(&name) + pub(crate) fn resolve_macro_call( + &self, + db: &impl HirDatabase, + path: Option, + ) -> Option { + let m = self.module()?; + m.0.find_macro(db, m.1, &path?) } /// Returns the resolved path segments diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 860e100694..75ed2de6cd 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -283,8 +283,13 @@ impl SourceAnalyzer { self.infer.as_ref()?.field_resolution(expr_id) } - pub fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option { - let id = self.resolver.resolve_macro_call(macro_call.path().and_then(Path::from_ast))?; + pub fn resolve_macro_call( + &self, + db: &impl HirDatabase, + macro_call: &ast::MacroCall, + ) -> Option { + let id = + self.resolver.resolve_macro_call(db, macro_call.path().and_then(Path::from_ast))?; Some(MacroByExampleDef { id }) } diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index 97b367115c..e72b7a6e7a 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs @@ -216,6 +216,29 @@ mod tests { ); } + #[test] + fn goto_definition_works_for_macros_from_other_crates() { + covers!(goto_definition_works_for_macros); + check_goto( + " + //- /lib.rs + use foo::foo; + fn bar() { + <|>foo!(); + } + + //- /foo/lib.rs + #[macro_export] + macro_rules! foo { + () => { + {} + }; + } + ", + "foo MACRO_CALL FileId(2) [0; 79) [29; 32)", + ); + } + #[test] fn goto_definition_works_for_methods() { covers!(goto_definition_works_for_methods); diff --git a/crates/ra_ide_api/src/name_ref_kind.rs b/crates/ra_ide_api/src/name_ref_kind.rs index b498fe4950..90972bc589 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( .and_then(ast::MacroCall::cast) { tested_by!(goto_definition_works_for_macros); - if let Some(mac) = analyzer.resolve_macro_call(macro_call) { + if let Some(mac) = analyzer.resolve_macro_call(db, macro_call) { return Some(Macro(mac)); } }