mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-30 15:03:42 +00:00
Goto type def through macros
This commit is contained in:
parent
7614439033
commit
e939f740b3
1 changed files with 29 additions and 7 deletions
|
@ -1,25 +1,28 @@
|
||||||
//! FIXME: write short doc here
|
//! FIXME: write short doc here
|
||||||
|
|
||||||
use ra_db::SourceDatabase;
|
use hir::db::AstDatabase;
|
||||||
use ra_syntax::{ast, AstNode};
|
use ra_syntax::{ast, AstNode};
|
||||||
|
|
||||||
use crate::{db::RootDatabase, display::ToNav, FilePosition, NavigationTarget, RangeInfo};
|
use crate::{
|
||||||
|
db::RootDatabase, display::ToNav, expand::descend_into_macros, FilePosition, NavigationTarget,
|
||||||
|
RangeInfo,
|
||||||
|
};
|
||||||
|
|
||||||
pub(crate) fn goto_type_definition(
|
pub(crate) fn goto_type_definition(
|
||||||
db: &RootDatabase,
|
db: &RootDatabase,
|
||||||
position: FilePosition,
|
position: FilePosition,
|
||||||
) -> Option<RangeInfo<Vec<NavigationTarget>>> {
|
) -> Option<RangeInfo<Vec<NavigationTarget>>> {
|
||||||
let parse = db.parse(position.file_id);
|
let file = db.parse_or_expand(position.file_id.into())?;
|
||||||
|
let token = file.token_at_offset(position.offset).filter(|it| !it.kind().is_trivia()).next()?;
|
||||||
|
let token = descend_into_macros(db, position.file_id, token);
|
||||||
|
|
||||||
let node = parse.tree().syntax().token_at_offset(position.offset).find_map(|token| {
|
let node = token.ast.ancestors().find_map(|token| {
|
||||||
token
|
token
|
||||||
.parent()
|
|
||||||
.ancestors()
|
.ancestors()
|
||||||
.find(|n| ast::Expr::cast(n.clone()).is_some() || ast::Pat::cast(n.clone()).is_some())
|
.find(|n| ast::Expr::cast(n.clone()).is_some() || ast::Pat::cast(n.clone()).is_some())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let analyzer =
|
let analyzer = hir::SourceAnalyzer::new(db, token.with_ast(&node), None);
|
||||||
hir::SourceAnalyzer::new(db, hir::Source::new(position.file_id.into(), &node), None);
|
|
||||||
|
|
||||||
let ty: hir::Ty = if let Some(ty) =
|
let ty: hir::Ty = if let Some(ty) =
|
||||||
ast::Expr::cast(node.clone()).and_then(|e| analyzer.type_of(db, &e))
|
ast::Expr::cast(node.clone()).and_then(|e| analyzer.type_of(db, &e))
|
||||||
|
@ -80,4 +83,23 @@ mod tests {
|
||||||
"Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)",
|
"Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn goto_type_definition_works_through_macro() {
|
||||||
|
check_goto(
|
||||||
|
"
|
||||||
|
//- /lib.rs
|
||||||
|
macro_rules! id {
|
||||||
|
($($tt:tt)*) => { $($tt)* }
|
||||||
|
}
|
||||||
|
struct Foo {}
|
||||||
|
id! {
|
||||||
|
fn bar() {
|
||||||
|
let f<|> = Foo {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"Foo STRUCT_DEF FileId(1) [52; 65) [59; 62)",
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue