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>, 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 { impl NavigationTarget {
/// When `focus_range` is specified, returns it. otherwise /// When `focus_range` is specified, returns it. otherwise
/// returns `full_range` /// returns `full_range`
@ -72,8 +86,12 @@ impl NavigationTarget {
self.focus_range self.focus_range
} }
pub(crate) fn from_bind_pat(file_id: FileId, pat: &ast::BindPat) -> NavigationTarget { pub(crate) fn from_bind_pat(
NavigationTarget::from_named(file_id, pat, None, None) 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 { pub(crate) fn from_symbol(db: &RootDatabase, symbol: FileSymbol) -> NavigationTarget {
@ -96,7 +114,7 @@ impl NavigationTarget {
) -> NavigationTarget { ) -> NavigationTarget {
let parse = db.parse(file_id); let parse = db.parse(file_id);
let pat = pat.to_node(parse.tree().syntax()); 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( pub(crate) fn from_self_param(
@ -119,31 +137,47 @@ impl NavigationTarget {
pub(crate) fn from_module(db: &RootDatabase, module: hir::Module) -> NavigationTarget { pub(crate) fn from_module(db: &RootDatabase, module: hir::Module) -> NavigationTarget {
let src = module.definition_source(db); 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(); let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default();
match src.ast { match src.ast {
ModuleSource::SourceFile(node) => { 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 { 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(); let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default();
if let Some(src) = module.declaration_source(db) { 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( return NavigationTarget::from_syntax(
file_id, file_id,
name, name,
None, None,
text_range,
src.ast.syntax(), src.ast.syntax(),
src.ast.doc_comment_text(), src.ast.doc_comment_text(),
src.ast.short_label(), src.ast.short_label(),
@ -154,13 +188,25 @@ impl NavigationTarget {
pub(crate) fn from_field(db: &RootDatabase, field: hir::StructField) -> NavigationTarget { pub(crate) fn from_field(db: &RootDatabase, field: hir::StructField) -> NavigationTarget {
let src = field.source(db); let src = field.source(db);
let file_id = src.file_id.original_file(db);
match src.ast { match src.ast {
FieldSource::Named(it) => { FieldSource::Named(it) => NavigationTarget::from_named(
NavigationTarget::from_named(file_id, &it, it.doc_comment_text(), it.short_label()) db,
} src.file_id,
&it,
it.doc_comment_text(),
it.short_label(),
),
FieldSource::Pos(it) => { 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); let src = def.source(db);
NavigationTarget::from_named( NavigationTarget::from_named(
src.file_id.original_file(db), db,
src.file_id,
&src.ast, &src.ast,
src.ast.doc_comment_text(), src.ast.doc_comment_text(),
src.ast.short_label(), src.ast.short_label(),
@ -212,10 +259,13 @@ impl NavigationTarget {
impl_block: hir::ImplBlock, impl_block: hir::ImplBlock,
) -> NavigationTarget { ) -> NavigationTarget {
let src = impl_block.source(db); 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( NavigationTarget::from_syntax(
src.file_id.original_file(db), file_id,
"impl".into(), "impl".into(),
None, None,
text_range,
src.ast.syntax(), src.ast.syntax(),
None, None,
None, None,
@ -236,12 +286,7 @@ impl NavigationTarget {
pub(crate) fn from_macro_def(db: &RootDatabase, macro_call: hir::MacroDef) -> NavigationTarget { pub(crate) fn from_macro_def(db: &RootDatabase, macro_call: hir::MacroDef) -> NavigationTarget {
let src = macro_call.source(db); let src = macro_call.source(db);
log::debug!("nav target {:#?}", src.ast.syntax()); log::debug!("nav target {:#?}", src.ast.syntax());
NavigationTarget::from_named( NavigationTarget::from_named(db, src.file_id, &src.ast, src.ast.doc_comment_text(), None)
src.file_id.original_file(db),
&src.ast,
src.ast.doc_comment_text(),
None,
)
} }
#[cfg(test)] #[cfg(test)]
@ -270,21 +315,35 @@ impl NavigationTarget {
/// Allows `NavigationTarget` to be created from a `NameOwner` /// Allows `NavigationTarget` to be created from a `NameOwner`
pub(crate) fn from_named( pub(crate) fn from_named(
file_id: FileId, db: &RootDatabase,
file_id: hir::HirFileId,
node: &impl ast::NameOwner, node: &impl ast::NameOwner,
docs: Option<String>, docs: Option<String>,
description: Option<String>, description: Option<String>,
) -> NavigationTarget { ) -> NavigationTarget {
//FIXME: use `_` instead of empty string //FIXME: use `_` instead of empty string
let name = node.name().map(|it| it.text().clone()).unwrap_or_default(); 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( fn from_syntax(
file_id: FileId, file_id: FileId,
name: SmolStr, name: SmolStr,
focus_range: Option<TextRange>, focus_range: Option<TextRange>,
full_range: TextRange,
node: &SyntaxNode, node: &SyntaxNode,
docs: Option<String>, docs: Option<String>,
description: Option<String>, description: Option<String>,
@ -293,9 +352,8 @@ impl NavigationTarget {
file_id, file_id,
name, name,
kind: node.kind(), kind: node.kind(),
full_range: node.text_range(), full_range,
focus_range, focus_range,
// ptr: Some(LocalSyntaxPtr::new(node)),
container_name: None, container_name: None,
description, description,
docs, 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]); return Some(vec![nav]);
} }
None 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_ast! {
match node { match node {
ast::StructDef(it) => { ast::StructDef(it) => {
Some(NavigationTarget::from_named( Some(NavigationTarget::from_named(
file_id, db,
file_id.into(),
&it, &it,
it.doc_comment_text(), it.doc_comment_text(),
it.short_label(), it.short_label(),
@ -121,7 +122,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
}, },
ast::EnumDef(it) => { ast::EnumDef(it) => {
Some(NavigationTarget::from_named( Some(NavigationTarget::from_named(
file_id, db,
file_id.into(),
&it, &it,
it.doc_comment_text(), it.doc_comment_text(),
it.short_label(), it.short_label(),
@ -129,7 +131,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
}, },
ast::EnumVariant(it) => { ast::EnumVariant(it) => {
Some(NavigationTarget::from_named( Some(NavigationTarget::from_named(
file_id, db,
file_id.into(),
&it, &it,
it.doc_comment_text(), it.doc_comment_text(),
it.short_label(), it.short_label(),
@ -137,7 +140,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
}, },
ast::FnDef(it) => { ast::FnDef(it) => {
Some(NavigationTarget::from_named( Some(NavigationTarget::from_named(
file_id, db,
file_id.into(),
&it, &it,
it.doc_comment_text(), it.doc_comment_text(),
it.short_label(), it.short_label(),
@ -145,7 +149,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
}, },
ast::TypeAliasDef(it) => { ast::TypeAliasDef(it) => {
Some(NavigationTarget::from_named( Some(NavigationTarget::from_named(
file_id, db,
file_id.into(),
&it, &it,
it.doc_comment_text(), it.doc_comment_text(),
it.short_label(), it.short_label(),
@ -153,7 +158,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
}, },
ast::ConstDef(it) => { ast::ConstDef(it) => {
Some(NavigationTarget::from_named( Some(NavigationTarget::from_named(
file_id, db,
file_id.into(),
&it, &it,
it.doc_comment_text(), it.doc_comment_text(),
it.short_label(), it.short_label(),
@ -161,7 +167,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
}, },
ast::StaticDef(it) => { ast::StaticDef(it) => {
Some(NavigationTarget::from_named( Some(NavigationTarget::from_named(
file_id, db,
file_id.into(),
&it, &it,
it.doc_comment_text(), it.doc_comment_text(),
it.short_label(), it.short_label(),
@ -169,7 +176,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
}, },
ast::TraitDef(it) => { ast::TraitDef(it) => {
Some(NavigationTarget::from_named( Some(NavigationTarget::from_named(
file_id, db,
file_id.into(),
&it, &it,
it.doc_comment_text(), it.doc_comment_text(),
it.short_label(), it.short_label(),
@ -177,7 +185,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
}, },
ast::RecordFieldDef(it) => { ast::RecordFieldDef(it) => {
Some(NavigationTarget::from_named( Some(NavigationTarget::from_named(
file_id, db,
file_id.into(),
&it, &it,
it.doc_comment_text(), it.doc_comment_text(),
it.short_label(), it.short_label(),
@ -185,7 +194,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
}, },
ast::Module(it) => { ast::Module(it) => {
Some(NavigationTarget::from_named( Some(NavigationTarget::from_named(
file_id, db,
file_id.into(),
&it, &it,
it.doc_comment_text(), it.doc_comment_text(),
it.short_label(), it.short_label(),
@ -193,7 +203,8 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
}, },
ast::MacroCall(it) => { ast::MacroCall(it) => {
Some(NavigationTarget::from_named( Some(NavigationTarget::from_named(
file_id, db,
file_id.into(),
&it, &it,
it.doc_comment_text(), it.doc_comment_text(),
None, None,