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,
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
}
}
+impl Docs for Struct {
+ fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> {
+ docs_from_ast(&*self.source(db).1)
+ }
+}
+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Enum {
pub(crate) def_id: DefId,
}
}
+impl Docs for Enum {
+ fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> {
+ docs_from_ast(&*self.source(db).1)
+ }
+}
+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct EnumVariant {
pub(crate) def_id: DefId,
}
}
+impl Docs for EnumVariant {
+ fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> {
+ docs_from_ast(&*self.source(db).1)
+ }
+}
+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Function {
pub(crate) def_id: DefId,
pub fn generic_params(&self, db: &impl HirDatabase) -> Arc<GenericParams> {
db.generic_params(self.def_id)
}
+}
- pub fn docs(&self, db: &impl HirDatabase) -> Option<String> {
- 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<Documentation> {
+ docs_from_ast(&*self.source(db).1)
}
}
--- /dev/null
+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<String> for Documentation {
+ fn into(self) -> String {
+ self.contents().into()
+ }
+}
+
+pub trait Docs {
+ fn docs(&self, db: &impl HirDatabase) -> Option<Documentation>;
+}
+
+pub(crate) fn docs_from_ast(node: &impl ast::DocCommentsOwner) -> Option<Documentation> {
+ let comments = node.doc_comment_text();
+ if comments.is_empty() {
+ None
+ } else {
+ Some(Documentation::new(&comments))
+ }
+}
mod impl_block;
mod expr;
mod generics;
+mod docs;
mod code_model_api;
mod code_model_impl;
ty::Ty,
impl_block::{ImplBlock, ImplItem},
code_model_impl::function::{FnScopes, ScopesWithSyntaxMapping},
+ docs::{Docs, Documentation}
};
pub use self::code_model_api::{
completion::{CompletionItem, CompletionItemKind, Completions, CompletionKind, CompletionContext},
};
+use hir::Docs;
+
pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
let (path, module) = match (&ctx.path_prefix, &ctx.module) {
(Some(path), Some(module)) => (path.clone(), module),
hir::Def::Enum(e) => {
e.variants(ctx.db)
.into_iter()
- .for_each(|(variant_name, _variant)| {
+ .for_each(|(variant_name, variant)| {
CompletionItem::new(
CompletionKind::Reference,
ctx.source_range(),
variant_name.to_string(),
)
.kind(CompletionItemKind::EnumVariant)
+ .set_documentation(variant.docs(ctx.db))
.add_to(acc)
});
}
-use hir::PerNs;
+use hir::{Docs, Documentation, PerNs};
use crate::completion::completion_context::CompletionContext;
use ra_syntax::{
label: String,
kind: Option<CompletionItemKind>,
detail: Option<String>,
- documentation: Option<String>,
+ documentation: Option<Documentation>,
lookup: Option<String>,
insert_text: Option<String>,
insert_text_format: InsertTextFormat,
}
/// A doc-comment
pub fn documentation(&self) -> Option<&str> {
- self.documentation.as_ref().map(|it| it.as_str())
+ self.documentation.as_ref().map(|it| it.contents())
}
/// What string is used for filtering.
pub fn lookup(&self) -> &str {
insert_text: Option<String>,
insert_text_format: InsertTextFormat,
detail: Option<String>,
- documentation: Option<String>,
+ documentation: Option<Documentation>,
lookup: Option<String>,
kind: Option<CompletionItemKind>,
text_edit: Option<TextEdit>,
self
}
#[allow(unused)]
- pub(crate) fn documentation(self, docs: impl Into<String>) -> Builder {
+ pub(crate) fn documentation(self, docs: Documentation) -> Builder {
self.set_documentation(Some(docs))
}
- pub(crate) fn set_documentation(mut self, docs: Option<impl Into<String>>) -> Builder {
+ pub(crate) fn set_documentation(mut self, docs: Option<Documentation>) -> Builder {
self.documentation = docs.map(Into::into);
self
}
}
self.insert_text_format = InsertTextFormat::Snippet;
}
+
if let Some(docs) = function.docs(ctx.db) {
self.documentation = Some(docs);
}