Use new expansion feature in goto_definition

This commit is contained in:
Edwin Cheng 2019-11-04 01:49:41 +08:00
parent 67226ebc82
commit e8741b9d75
2 changed files with 114 additions and 45 deletions

View file

@ -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,

View file

@ -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,