From d7be1a437239770552199028259639e6dfa8a664 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sun, 12 Jan 2020 18:08:53 +0800 Subject: Use attr location for builtin macro goto-imp --- crates/ra_hir/src/code_model.rs | 24 +++++++++++++++++++++++- crates/ra_hir_expand/src/lib.rs | 15 +++++++++++++++ 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::{ }; use ra_db::{CrateId, Edition, FileId}; use ra_prof::profile; -use ra_syntax::ast; +use ra_syntax::ast::{self, AttrsOwner}; use crate::{ db::{DefDatabase, HirDatabase}, + has_source::HasSource, CallableDef, HirDisplay, InFile, Name, }; @@ -805,6 +806,27 @@ impl ImplBlock { pub fn krate(&self, db: &impl DefDatabase) -> Crate { Crate { id: self.module(db).id.krate } } + + pub fn is_builtin_derive(&self, db: &impl DefDatabase) -> Option> { + let src = self.source(db); + let item = src.file_id.is_builtin_derive(db)?; + let hygenic = hir_expand::hygiene::Hygiene::new(db, item.file_id); + + let attr = item + .value + .attrs() + .filter_map(|it| { + let path = hir_def::path::ModPath::from_src(it.path()?, &hygenic)?; + if path.as_ident()?.to_string() == "derive" { + Some(it) + } else { + None + } + }) + .last()?; + + Some(item.with_value(attr)) + } } #[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 { } } } + + /// Indicate it is macro file generated for builtin derive + pub fn is_builtin_derive(&self, db: &dyn db::AstDatabase) -> Option> { + match self.0 { + HirFileIdRepr::FileId(_) => None, + HirFileIdRepr::MacroFile(macro_file) => { + let loc: MacroCallLoc = db.lookup_intern_macro(macro_file.macro_call_id); + let item = match loc.def.kind { + MacroDefKind::BuiltInDerive(_) => loc.kind.node(db), + _ => return None, + }; + Some(item.with_value(ast::ModuleItem::cast(item.value.clone())?)) + } + } + } } #[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 { impl ToNav for hir::ImplBlock { fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { let src = self.source(db); - let frange = original_range(db, src.as_ref().map(|it| it.syntax())); + let frange = if let Some(item) = self.is_builtin_derive(db) { + original_range(db, item.syntax()) + } else { + original_range(db, src.as_ref().map(|it| it.syntax())) + }; NavigationTarget::from_syntax( frange.file_id, -- cgit v1.2.3 From db5f73d261413f03e4e3a4a374f8306fe8ae5578 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sun, 12 Jan 2020 19:24:34 +0800 Subject: Add test --- crates/ra_ide/src/impls.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/crates/ra_ide/src/impls.rs b/crates/ra_ide/src/impls.rs index 9b165ee2a..31195036e 100644 --- a/crates/ra_ide/src/impls.rs +++ b/crates/ra_ide/src/impls.rs @@ -203,4 +203,16 @@ mod tests { ], ); } + + #[test] + fn goto_implementation_to_builtin_derive() { + check_goto( + " + //- /lib.rs + #[derive(Copy)] + struct Foo<|>; + ", + &["impl IMPL_BLOCK FileId(1) [0; 15)"], + ); + } } -- cgit v1.2.3