From 576625f0a1c6e54075d173db7e691d75077ca677 Mon Sep 17 00:00:00 2001 From: "Jeremy A. Kolb" Date: Wed, 23 Jan 2019 16:22:10 -0500 Subject: Add way of getting docs from the code model and use for completion --- crates/ra_hir/src/code_model_api.rs | 37 ++++++++++++++++++++++++------------- crates/ra_hir/src/docs.rs | 35 +++++++++++++++++++++++++++++++++++ crates/ra_hir/src/lib.rs | 2 ++ 3 files changed, 61 insertions(+), 13 deletions(-) create mode 100644 crates/ra_hir/src/docs.rs (limited to 'crates/ra_hir') diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index 9ae620efd..333d117f1 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use relative_path::RelativePathBuf; use ra_db::{CrateId, FileId}; -use ra_syntax::{ast::{self, AstNode, DocCommentsOwner}, TreeArc, SyntaxNode}; +use ra_syntax::{ast::self, TreeArc, SyntaxNode}; use crate::{ Name, DefId, Path, PerNs, ScopesWithSyntaxMapping, Ty, HirFileId, @@ -14,6 +14,7 @@ use crate::{ adt::VariantData, generics::GenericParams, code_model_impl::def_id_to_ast, + docs::{Documentation, Docs, docs_from_ast} }; /// hir::Crate describes a single crate. It's the main interface with which @@ -208,6 +209,12 @@ impl Struct { } } +impl Docs for Struct { + fn docs(&self, db: &impl HirDatabase) -> Option { + docs_from_ast(&*self.source(db).1) + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Enum { pub(crate) def_id: DefId, @@ -239,6 +246,12 @@ impl Enum { } } +impl Docs for Enum { + fn docs(&self, db: &impl HirDatabase) -> Option { + docs_from_ast(&*self.source(db).1) + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct EnumVariant { pub(crate) def_id: DefId, @@ -281,6 +294,12 @@ impl EnumVariant { } } +impl Docs for EnumVariant { + fn docs(&self, db: &impl HirDatabase) -> Option { + docs_from_ast(&*self.source(db).1) + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Function { pub(crate) def_id: DefId, @@ -352,19 +371,11 @@ impl Function { pub fn generic_params(&self, db: &impl HirDatabase) -> Arc { db.generic_params(self.def_id) } +} - pub fn docs(&self, db: &impl HirDatabase) -> Option { - let def_loc = self.def_id.loc(db); - let syntax = db.file_item(def_loc.source_item_id); - let fn_def = ast::FnDef::cast(&syntax).expect("fn def should point to FnDef node"); - - // doc_comment_text unconditionally returns a String - let comments = fn_def.doc_comment_text(); - if comments.is_empty() { - None - } else { - Some(comments) - } +impl Docs for Function { + fn docs(&self, db: &impl HirDatabase) -> Option { + docs_from_ast(&*self.source(db).1) } } diff --git a/crates/ra_hir/src/docs.rs b/crates/ra_hir/src/docs.rs new file mode 100644 index 000000000..330d8f8f4 --- /dev/null +++ b/crates/ra_hir/src/docs.rs @@ -0,0 +1,35 @@ +use ra_syntax::ast; + +use crate::HirDatabase; + +#[derive(Debug, Clone)] +pub struct Documentation(String); + +impl Documentation { + pub fn new(s: &str) -> Self { + Self(s.into()) + } + + pub fn contents(&self) -> &str { + &self.0 + } +} + +impl Into for Documentation { + fn into(self) -> String { + self.contents().into() + } +} + +pub trait Docs { + fn docs(&self, db: &impl HirDatabase) -> Option; +} + +pub(crate) fn docs_from_ast(node: &impl ast::DocCommentsOwner) -> Option { + let comments = node.doc_comment_text(); + if comments.is_empty() { + None + } else { + Some(Documentation::new(&comments)) + } +} diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index a861ee88e..f517f71e0 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs @@ -23,6 +23,7 @@ mod ty; mod impl_block; mod expr; mod generics; +mod docs; mod code_model_api; mod code_model_impl; @@ -45,6 +46,7 @@ pub use self::{ ty::Ty, impl_block::{ImplBlock, ImplItem}, code_model_impl::function::{FnScopes, ScopesWithSyntaxMapping}, + docs::{Docs, Documentation} }; pub use self::code_model_api::{ -- cgit v1.2.3