Merge #2807
2807: Use attr location for builtin derive in goto-implementation r=matklad a=edwin0cheng This PR is use attribute location for builtin derive in `ImplBlock`'s NavigationTarget such that the goto-implementation will goto to a correct position. Related to #2531 Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
This commit is contained in:
commit
8bb2a50ce6
@ -26,10 +26,11 @@ use hir_ty::{
|
|||||||
};
|
};
|
||||||
use ra_db::{CrateId, Edition, FileId};
|
use ra_db::{CrateId, Edition, FileId};
|
||||||
use ra_prof::profile;
|
use ra_prof::profile;
|
||||||
use ra_syntax::ast;
|
use ra_syntax::ast::{self, AttrsOwner};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::{DefDatabase, HirDatabase},
|
db::{DefDatabase, HirDatabase},
|
||||||
|
has_source::HasSource,
|
||||||
CallableDef, HirDisplay, InFile, Name,
|
CallableDef, HirDisplay, InFile, Name,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -805,6 +806,27 @@ impl ImplBlock {
|
|||||||
pub fn krate(&self, db: &impl DefDatabase) -> Crate {
|
pub fn krate(&self, db: &impl DefDatabase) -> Crate {
|
||||||
Crate { id: self.module(db).id.krate }
|
Crate { id: self.module(db).id.krate }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_builtin_derive(&self, db: &impl DefDatabase) -> Option<InFile<ast::Attr>> {
|
||||||
|
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)]
|
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||||
|
@ -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<InFile<ast::ModuleItem>> {
|
||||||
|
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)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
@ -251,7 +251,11 @@ impl ToNav for hir::Module {
|
|||||||
impl ToNav for hir::ImplBlock {
|
impl ToNav for hir::ImplBlock {
|
||||||
fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
|
fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
|
||||||
let src = self.source(db);
|
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(
|
NavigationTarget::from_syntax(
|
||||||
frange.file_id,
|
frange.file_id,
|
||||||
|
@ -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)"],
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user