mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 13:33:31 +00:00
Use new expansion feature in goto_definition
This commit is contained in:
parent
67226ebc82
commit
e8741b9d75
2 changed files with 114 additions and 45 deletions
|
@ -29,6 +29,20 @@ pub struct NavigationTarget {
|
|||
docs: Option<String>,
|
||||
}
|
||||
|
||||
fn find_range_from_node(
|
||||
db: &RootDatabase,
|
||||
src: hir::HirFileId,
|
||||
node: &SyntaxNode,
|
||||
) -> (FileId, TextRange) {
|
||||
let text_range = node.text_range();
|
||||
let (file_id, text_range) = src
|
||||
.parent_expansion(db)
|
||||
.and_then(|(files, expansion_info)| expansion_info.find_range(text_range, files))
|
||||
.unwrap_or((src, text_range));
|
||||
|
||||
(file_id.original_file(db), text_range)
|
||||
}
|
||||
|
||||
impl NavigationTarget {
|
||||
/// When `focus_range` is specified, returns it. otherwise
|
||||
/// returns `full_range`
|
||||
|
@ -72,8 +86,12 @@ impl NavigationTarget {
|
|||
self.focus_range
|
||||
}
|
||||
|
||||
pub(crate) fn from_bind_pat(file_id: FileId, pat: &ast::BindPat) -> NavigationTarget {
|
||||
NavigationTarget::from_named(file_id, pat, None, None)
|
||||
pub(crate) fn from_bind_pat(
|
||||
db: &RootDatabase,
|
||||
file_id: FileId,
|
||||
pat: &ast::BindPat,
|
||||
) -> NavigationTarget {
|
||||
NavigationTarget::from_named(db, file_id.into(), pat, None, None)
|
||||
}
|
||||
|
||||
pub(crate) fn from_symbol(db: &RootDatabase, symbol: FileSymbol) -> NavigationTarget {
|
||||
|
@ -96,7 +114,7 @@ impl NavigationTarget {
|
|||
) -> NavigationTarget {
|
||||
let parse = db.parse(file_id);
|
||||
let pat = pat.to_node(parse.tree().syntax());
|
||||
NavigationTarget::from_bind_pat(file_id, &pat)
|
||||
NavigationTarget::from_bind_pat(db, file_id, &pat)
|
||||
}
|
||||
|
||||
pub(crate) fn from_self_param(
|
||||
|
@ -119,31 +137,47 @@ impl NavigationTarget {
|
|||
|
||||
pub(crate) fn from_module(db: &RootDatabase, module: hir::Module) -> NavigationTarget {
|
||||
let src = module.definition_source(db);
|
||||
let file_id = src.file_id.original_file(db);
|
||||
let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default();
|
||||
|
||||
match src.ast {
|
||||
ModuleSource::SourceFile(node) => {
|
||||
NavigationTarget::from_syntax(file_id, name, None, node.syntax(), None, None)
|
||||
let (file_id, text_range) = find_range_from_node(db, src.file_id, node.syntax());
|
||||
|
||||
NavigationTarget::from_syntax(
|
||||
file_id,
|
||||
name,
|
||||
None,
|
||||
text_range,
|
||||
node.syntax(),
|
||||
None,
|
||||
None,
|
||||
)
|
||||
}
|
||||
ModuleSource::Module(node) => {
|
||||
let (file_id, text_range) = find_range_from_node(db, src.file_id, node.syntax());
|
||||
|
||||
NavigationTarget::from_syntax(
|
||||
file_id,
|
||||
name,
|
||||
None,
|
||||
text_range,
|
||||
node.syntax(),
|
||||
node.doc_comment_text(),
|
||||
node.short_label(),
|
||||
)
|
||||
}
|
||||
ModuleSource::Module(node) => NavigationTarget::from_syntax(
|
||||
file_id,
|
||||
name,
|
||||
None,
|
||||
node.syntax(),
|
||||
node.doc_comment_text(),
|
||||
node.short_label(),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn from_module_to_decl(db: &RootDatabase, module: hir::Module) -> NavigationTarget {
|
||||
let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default();
|
||||
if let Some(src) = module.declaration_source(db) {
|
||||
let file_id = src.file_id.original_file(db);
|
||||
let (file_id, text_range) = find_range_from_node(db, src.file_id, src.ast.syntax());
|
||||
return NavigationTarget::from_syntax(
|
||||
file_id,
|
||||
name,
|
||||
None,
|
||||
text_range,
|
||||
src.ast.syntax(),
|
||||
src.ast.doc_comment_text(),
|
||||
src.ast.short_label(),
|
||||
|
@ -154,13 +188,25 @@ impl NavigationTarget {
|
|||
|
||||
pub(crate) fn from_field(db: &RootDatabase, field: hir::StructField) -> NavigationTarget {
|
||||
let src = field.source(db);
|
||||
let file_id = src.file_id.original_file(db);
|
||||
match src.ast {
|
||||
FieldSource::Named(it) => {
|
||||
NavigationTarget::from_named(file_id, &it, it.doc_comment_text(), it.short_label())
|
||||
}
|
||||
FieldSource::Named(it) => NavigationTarget::from_named(
|
||||
db,
|
||||
src.file_id,
|
||||
&it,
|
||||
it.doc_comment_text(),
|
||||
it.short_label(),
|
||||
),
|
||||
FieldSource::Pos(it) => {
|
||||
NavigationTarget::from_syntax(file_id, "".into(), None, it.syntax(), None, None)
|
||||
let (file_id, text_range) = find_range_from_node(db, src.file_id, it.syntax());
|
||||
NavigationTarget::from_syntax(
|
||||
file_id,
|
||||
"".into(),
|
||||
None,
|
||||
text_range,
|
||||
it.syntax(),
|
||||
None,
|
||||
None,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -172,7 +218,8 @@ impl NavigationTarget {
|
|||
{
|
||||
let src = def.source(db);
|
||||
NavigationTarget::from_named(
|
||||
src.file_id.original_file(db),
|
||||
db,
|
||||
src.file_id,
|
||||
&src.ast,
|
||||
src.ast.doc_comment_text(),
|
||||
src.ast.short_label(),
|
||||
|
@ -212,10 +259,13 @@ impl NavigationTarget {
|
|||
impl_block: hir::ImplBlock,
|
||||
) -> NavigationTarget {
|
||||
let src = impl_block.source(db);
|
||||
let (file_id, text_range) = find_range_from_node(db, src.file_id, src.ast.syntax());
|
||||
|
||||
NavigationTarget::from_syntax(
|
||||
src.file_id.original_file(db),
|
||||
file_id,
|
||||
"impl".into(),
|
||||
None,
|
||||
text_range,
|
||||
src.ast.syntax(),
|
||||
None,
|
||||
None,
|
||||
|
@ -236,12 +286,7 @@ impl NavigationTarget {
|
|||
pub(crate) fn from_macro_def(db: &RootDatabase, macro_call: hir::MacroDef) -> NavigationTarget {
|
||||
let src = macro_call.source(db);
|
||||
log::debug!("nav target {:#?}", src.ast.syntax());
|
||||
NavigationTarget::from_named(
|
||||
src.file_id.original_file(db),
|
||||
&src.ast,
|
||||
src.ast.doc_comment_text(),
|
||||
None,
|
||||
)
|
||||
NavigationTarget::from_named(db, src.file_id, &src.ast, src.ast.doc_comment_text(), None)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -270,21 +315,35 @@ impl NavigationTarget {
|
|||
|
||||
/// Allows `NavigationTarget` to be created from a `NameOwner`
|
||||
pub(crate) fn from_named(
|
||||
file_id: FileId,
|
||||
db: &RootDatabase,
|
||||
file_id: hir::HirFileId,
|
||||
node: &impl ast::NameOwner,
|
||||
docs: Option<String>,
|
||||
description: Option<String>,
|
||||
) -> NavigationTarget {
|
||||
//FIXME: use `_` instead of empty string
|
||||
let name = node.name().map(|it| it.text().clone()).unwrap_or_default();
|
||||
let focus_range = node.name().map(|it| it.syntax().text_range());
|
||||
NavigationTarget::from_syntax(file_id, name, focus_range, node.syntax(), docs, description)
|
||||
|
||||
let focus_range = node.name().map(|it| find_range_from_node(db, file_id, it.syntax()).1);
|
||||
|
||||
let (file_id, full_range) = find_range_from_node(db, file_id, node.syntax());
|
||||
|
||||
NavigationTarget::from_syntax(
|
||||
file_id,
|
||||
name,
|
||||
focus_range,
|
||||
full_range,
|
||||
node.syntax(),
|
||||
docs,
|
||||
description,
|
||||
)
|
||||
}
|
||||
|
||||
fn from_syntax(
|
||||
file_id: FileId,
|
||||
name: SmolStr,
|
||||
focus_range: Option<TextRange>,
|
||||
full_range: TextRange,
|
||||
node: &SyntaxNode,
|
||||
docs: Option<String>,
|
||||
description: Option<String>,
|
||||
|
@ -293,9 +352,8 @@ impl NavigationTarget {
|
|||
file_id,
|
||||
name,
|
||||
kind: node.kind(),
|
||||
full_range: node.text_range(),
|
||||
full_range,
|
||||
focus_range,
|
||||
// ptr: Some(LocalSyntaxPtr::new(node)),
|
||||
container_name: None,
|
||||
description,
|
||||
docs,
|
||||
|
|
|
@ -101,19 +101,20 @@ pub(crate) fn name_definition(
|
|||
}
|
||||
}
|
||||
|
||||
if let Some(nav) = named_target(file_id, &parent) {
|
||||
if let Some(nav) = named_target(db, file_id, &parent) {
|
||||
return Some(vec![nav]);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget> {
|
||||
fn named_target(db: &RootDatabase, file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget> {
|
||||
match_ast! {
|
||||
match node {
|
||||
ast::StructDef(it) => {
|
||||
Some(NavigationTarget::from_named(
|
||||
file_id,
|
||||
db,
|
||||
file_id.into(),
|
||||
&it,
|
||||
it.doc_comment_text(),
|
||||
it.short_label(),
|
||||
|
@ -121,7 +122,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
|
|||
},
|
||||
ast::EnumDef(it) => {
|
||||
Some(NavigationTarget::from_named(
|
||||
file_id,
|
||||
db,
|
||||
file_id.into(),
|
||||
&it,
|
||||
it.doc_comment_text(),
|
||||
it.short_label(),
|
||||
|
@ -129,7 +131,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
|
|||
},
|
||||
ast::EnumVariant(it) => {
|
||||
Some(NavigationTarget::from_named(
|
||||
file_id,
|
||||
db,
|
||||
file_id.into(),
|
||||
&it,
|
||||
it.doc_comment_text(),
|
||||
it.short_label(),
|
||||
|
@ -137,7 +140,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
|
|||
},
|
||||
ast::FnDef(it) => {
|
||||
Some(NavigationTarget::from_named(
|
||||
file_id,
|
||||
db,
|
||||
file_id.into(),
|
||||
&it,
|
||||
it.doc_comment_text(),
|
||||
it.short_label(),
|
||||
|
@ -145,7 +149,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
|
|||
},
|
||||
ast::TypeAliasDef(it) => {
|
||||
Some(NavigationTarget::from_named(
|
||||
file_id,
|
||||
db,
|
||||
file_id.into(),
|
||||
&it,
|
||||
it.doc_comment_text(),
|
||||
it.short_label(),
|
||||
|
@ -153,7 +158,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
|
|||
},
|
||||
ast::ConstDef(it) => {
|
||||
Some(NavigationTarget::from_named(
|
||||
file_id,
|
||||
db,
|
||||
file_id.into(),
|
||||
&it,
|
||||
it.doc_comment_text(),
|
||||
it.short_label(),
|
||||
|
@ -161,7 +167,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
|
|||
},
|
||||
ast::StaticDef(it) => {
|
||||
Some(NavigationTarget::from_named(
|
||||
file_id,
|
||||
db,
|
||||
file_id.into(),
|
||||
&it,
|
||||
it.doc_comment_text(),
|
||||
it.short_label(),
|
||||
|
@ -169,7 +176,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
|
|||
},
|
||||
ast::TraitDef(it) => {
|
||||
Some(NavigationTarget::from_named(
|
||||
file_id,
|
||||
db,
|
||||
file_id.into(),
|
||||
&it,
|
||||
it.doc_comment_text(),
|
||||
it.short_label(),
|
||||
|
@ -177,7 +185,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
|
|||
},
|
||||
ast::RecordFieldDef(it) => {
|
||||
Some(NavigationTarget::from_named(
|
||||
file_id,
|
||||
db,
|
||||
file_id.into(),
|
||||
&it,
|
||||
it.doc_comment_text(),
|
||||
it.short_label(),
|
||||
|
@ -185,7 +194,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
|
|||
},
|
||||
ast::Module(it) => {
|
||||
Some(NavigationTarget::from_named(
|
||||
file_id,
|
||||
db,
|
||||
file_id.into(),
|
||||
&it,
|
||||
it.doc_comment_text(),
|
||||
it.short_label(),
|
||||
|
@ -193,7 +203,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
|
|||
},
|
||||
ast::MacroCall(it) => {
|
||||
Some(NavigationTarget::from_named(
|
||||
file_id,
|
||||
db,
|
||||
file_id.into(),
|
||||
&it,
|
||||
it.doc_comment_text(),
|
||||
None,
|
||||
|
|
Loading…
Reference in a new issue