diff options
author | Edwin Cheng <[email protected]> | 2020-01-12 10:08:53 +0000 |
---|---|---|
committer | Edwin Cheng <[email protected]> | 2020-01-12 10:08:53 +0000 |
commit | d7be1a437239770552199028259639e6dfa8a664 (patch) | |
tree | 3b1d063a8f9b8786924577d6ebc16dd9aa682d51 | |
parent | 86d2af9f7b3f6af2ea9e4eca2584aa501b60aa14 (diff) |
Use attr location for builtin macro goto-imp
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 24 | ||||
-rw-r--r-- | crates/ra_hir_expand/src/lib.rs | 15 | ||||
-rw-r--r-- | crates/ra_ide/src/display/navigation_target.rs | 6 |
3 files changed, 43 insertions, 2 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index df9c151e5..a177cebca 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -26,10 +26,11 @@ use hir_ty::{ | |||
26 | }; | 26 | }; |
27 | use ra_db::{CrateId, Edition, FileId}; | 27 | use ra_db::{CrateId, Edition, FileId}; |
28 | use ra_prof::profile; | 28 | use ra_prof::profile; |
29 | use ra_syntax::ast; | 29 | use ra_syntax::ast::{self, AttrsOwner}; |
30 | 30 | ||
31 | use crate::{ | 31 | use crate::{ |
32 | db::{DefDatabase, HirDatabase}, | 32 | db::{DefDatabase, HirDatabase}, |
33 | has_source::HasSource, | ||
33 | CallableDef, HirDisplay, InFile, Name, | 34 | CallableDef, HirDisplay, InFile, Name, |
34 | }; | 35 | }; |
35 | 36 | ||
@@ -805,6 +806,27 @@ impl ImplBlock { | |||
805 | pub fn krate(&self, db: &impl DefDatabase) -> Crate { | 806 | pub fn krate(&self, db: &impl DefDatabase) -> Crate { |
806 | Crate { id: self.module(db).id.krate } | 807 | Crate { id: self.module(db).id.krate } |
807 | } | 808 | } |
809 | |||
810 | pub fn is_builtin_derive(&self, db: &impl DefDatabase) -> Option<InFile<ast::Attr>> { | ||
811 | let src = self.source(db); | ||
812 | let item = src.file_id.is_builtin_derive(db)?; | ||
813 | let hygenic = hir_expand::hygiene::Hygiene::new(db, item.file_id); | ||
814 | |||
815 | let attr = item | ||
816 | .value | ||
817 | .attrs() | ||
818 | .filter_map(|it| { | ||
819 | let path = hir_def::path::ModPath::from_src(it.path()?, &hygenic)?; | ||
820 | if path.as_ident()?.to_string() == "derive" { | ||
821 | Some(it) | ||
822 | } else { | ||
823 | None | ||
824 | } | ||
825 | }) | ||
826 | .last()?; | ||
827 | |||
828 | Some(item.with_value(attr)) | ||
829 | } | ||
808 | } | 830 | } |
809 | 831 | ||
810 | #[derive(Clone, PartialEq, Eq, Debug)] | 832 | #[derive(Clone, PartialEq, Eq, Debug)] |
diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs index 51c5f9623..7cf3b59a7 100644 --- a/crates/ra_hir_expand/src/lib.rs +++ b/crates/ra_hir_expand/src/lib.rs | |||
@@ -112,6 +112,21 @@ impl HirFileId { | |||
112 | } | 112 | } |
113 | } | 113 | } |
114 | } | 114 | } |
115 | |||
116 | /// Indicate it is macro file generated for builtin derive | ||
117 | pub fn is_builtin_derive(&self, db: &dyn db::AstDatabase) -> Option<InFile<ast::ModuleItem>> { | ||
118 | match self.0 { | ||
119 | HirFileIdRepr::FileId(_) => None, | ||
120 | HirFileIdRepr::MacroFile(macro_file) => { | ||
121 | let loc: MacroCallLoc = db.lookup_intern_macro(macro_file.macro_call_id); | ||
122 | let item = match loc.def.kind { | ||
123 | MacroDefKind::BuiltInDerive(_) => loc.kind.node(db), | ||
124 | _ => return None, | ||
125 | }; | ||
126 | Some(item.with_value(ast::ModuleItem::cast(item.value.clone())?)) | ||
127 | } | ||
128 | } | ||
129 | } | ||
115 | } | 130 | } |
116 | 131 | ||
117 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 132 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
diff --git a/crates/ra_ide/src/display/navigation_target.rs b/crates/ra_ide/src/display/navigation_target.rs index f2e45fa31..b2af3479c 100644 --- a/crates/ra_ide/src/display/navigation_target.rs +++ b/crates/ra_ide/src/display/navigation_target.rs | |||
@@ -251,7 +251,11 @@ impl ToNav for hir::Module { | |||
251 | impl ToNav for hir::ImplBlock { | 251 | impl ToNav for hir::ImplBlock { |
252 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { | 252 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { |
253 | let src = self.source(db); | 253 | let src = self.source(db); |
254 | let frange = original_range(db, src.as_ref().map(|it| it.syntax())); | 254 | let frange = if let Some(item) = self.is_builtin_derive(db) { |
255 | original_range(db, item.syntax()) | ||
256 | } else { | ||
257 | original_range(db, src.as_ref().map(|it| it.syntax())) | ||
258 | }; | ||
255 | 259 | ||
256 | NavigationTarget::from_syntax( | 260 | NavigationTarget::from_syntax( |
257 | frange.file_id, | 261 | frange.file_id, |