aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorEdwin Cheng <[email protected]>2019-06-01 12:34:19 +0100
committerEdwin Cheng <[email protected]>2019-06-01 12:34:19 +0100
commit371961be0e0b0741599ebf3d9435c03fd45cf777 (patch)
tree21ffd6c02196fc8419abf15f1206b9608378b234 /crates
parent6c1ec865fb931ffd789e2caa9e2ce82d1df97c4d (diff)
Improve goto definition for MBE
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/expr.rs2
-rw-r--r--crates/ra_hir/src/nameres.rs18
-rw-r--r--crates/ra_hir/src/resolve.rs10
-rw-r--r--crates/ra_hir/src/source_binder.rs9
-rw-r--r--crates/ra_ide_api/src/goto_definition.rs23
-rw-r--r--crates/ra_ide_api/src/name_ref_kind.rs2
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 }