Introduce HasSource trait

This commit is contained in:
Aleksey Kladov 2019-06-11 16:40:49 +03:00
parent 2a1fe26b6d
commit 36865adcb9
3 changed files with 45 additions and 29 deletions

View File

@ -31,6 +31,11 @@ impl<T> From<(HirFileId, T)> for Source<T> {
}
}
pub trait HasSource {
type Ast;
fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<Self::Ast>;
}
/// hir::Crate describes a single crate. It's the main interface with which
/// a crate's dependencies interact. Mostly, it should be just a proxy for the
/// root module.
@ -364,6 +369,13 @@ pub struct Struct {
pub(crate) id: StructId,
}
impl HasSource for Struct {
type Ast = TreeArc<ast::StructDef>;
fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<TreeArc<ast::StructDef>> {
self.id.source(db).into()
}
}
impl Struct {
pub fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<TreeArc<ast::StructDef>> {
self.id.source(db).into()
@ -422,6 +434,13 @@ pub struct Union {
pub(crate) id: StructId,
}
impl HasSource for Union {
type Ast = TreeArc<ast::StructDef>;
fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<TreeArc<ast::StructDef>> {
self.id.source(db).into()
}
}
impl Union {
pub fn source(
self,
@ -455,6 +474,13 @@ pub struct Enum {
pub(crate) id: EnumId,
}
impl HasSource for Enum {
type Ast = TreeArc<ast::EnumDef>;
fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<TreeArc<ast::EnumDef>> {
self.id.source(db).into()
}
}
impl Enum {
pub fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<TreeArc<ast::EnumDef>> {
self.id.source(db).into()

View File

@ -81,5 +81,5 @@ pub use self::code_model::{
StructField, FieldSource,
Static, Const, ConstSignature,
Trait, TypeAlias, MacroDef, Container,
BuiltinType, Source,
BuiltinType, Source, HasSource,
};

View File

@ -1,6 +1,6 @@
use ra_db::{FileId, SourceDatabase};
use ra_syntax::{
SyntaxNode, AstNode, SmolStr, TextRange, AstPtr,
SyntaxNode, AstNode, SmolStr, TextRange, AstPtr, TreeArc,
SyntaxKind::{self, NAME},
ast::{self, DocCommentsOwner},
algo::visit::{visitor, Visitor},
@ -186,35 +186,25 @@ impl NavigationTarget {
}
}
pub(crate) fn from_def_source<A, D>(db: &RootDatabase, def: D) -> NavigationTarget
where
D: hir::HasSource<Ast = TreeArc<A>>,
A: ast::DocCommentsOwner + ast::NameOwner + ShortLabel,
{
let src = def.source(db);
NavigationTarget::from_named(
src.file_id.original_file(db),
&*src.ast,
src.ast.doc_comment_text(),
src.ast.short_label(),
)
}
pub(crate) fn from_adt_def(db: &RootDatabase, adt_def: hir::AdtDef) -> NavigationTarget {
match adt_def {
hir::AdtDef::Struct(s) => {
let src = s.source(db);
NavigationTarget::from_named(
src.file_id.original_file(db),
&*src.ast,
src.ast.doc_comment_text(),
src.ast.short_label(),
)
}
hir::AdtDef::Union(s) => {
let (file_id, node) = s.source(db);
NavigationTarget::from_named(
file_id.original_file(db),
&*node,
node.doc_comment_text(),
node.short_label(),
)
}
hir::AdtDef::Enum(s) => {
let src = s.source(db);
NavigationTarget::from_named(
src.file_id.original_file(db),
&*src.ast,
src.ast.doc_comment_text(),
src.ast.short_label(),
)
}
hir::AdtDef::Struct(it) => NavigationTarget::from_def_source(db, it),
hir::AdtDef::Union(it) => NavigationTarget::from_def_source(db, it),
hir::AdtDef::Enum(it) => NavigationTarget::from_def_source(db, it),
}
}