aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/code_model_api.rs37
-rw-r--r--crates/ra_hir/src/docs.rs35
-rw-r--r--crates/ra_hir/src/lib.rs2
-rw-r--r--crates/ra_ide_api/src/completion/complete_path.rs5
-rw-r--r--crates/ra_ide_api/src/completion/completion_item.rs13
5 files changed, 72 insertions, 20 deletions
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;
2 2
3use relative_path::RelativePathBuf; 3use relative_path::RelativePathBuf;
4use ra_db::{CrateId, FileId}; 4use ra_db::{CrateId, FileId};
5use ra_syntax::{ast::{self, AstNode, DocCommentsOwner}, TreeArc, SyntaxNode}; 5use ra_syntax::{ast::self, TreeArc, SyntaxNode};
6 6
7use crate::{ 7use crate::{
8 Name, DefId, Path, PerNs, ScopesWithSyntaxMapping, Ty, HirFileId, 8 Name, DefId, Path, PerNs, ScopesWithSyntaxMapping, Ty, HirFileId,
@@ -14,6 +14,7 @@ use crate::{
14 adt::VariantData, 14 adt::VariantData,
15 generics::GenericParams, 15 generics::GenericParams,
16 code_model_impl::def_id_to_ast, 16 code_model_impl::def_id_to_ast,
17 docs::{Documentation, Docs, docs_from_ast}
17}; 18};
18 19
19/// hir::Crate describes a single crate. It's the main interface with which 20/// hir::Crate describes a single crate. It's the main interface with which
@@ -208,6 +209,12 @@ impl Struct {
208 } 209 }
209} 210}
210 211
212impl Docs for Struct {
213 fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> {
214 docs_from_ast(&*self.source(db).1)
215 }
216}
217
211#[derive(Debug, Clone, PartialEq, Eq, Hash)] 218#[derive(Debug, Clone, PartialEq, Eq, Hash)]
212pub struct Enum { 219pub struct Enum {
213 pub(crate) def_id: DefId, 220 pub(crate) def_id: DefId,
@@ -239,6 +246,12 @@ impl Enum {
239 } 246 }
240} 247}
241 248
249impl Docs for Enum {
250 fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> {
251 docs_from_ast(&*self.source(db).1)
252 }
253}
254
242#[derive(Debug, Clone, PartialEq, Eq, Hash)] 255#[derive(Debug, Clone, PartialEq, Eq, Hash)]
243pub struct EnumVariant { 256pub struct EnumVariant {
244 pub(crate) def_id: DefId, 257 pub(crate) def_id: DefId,
@@ -281,6 +294,12 @@ impl EnumVariant {
281 } 294 }
282} 295}
283 296
297impl Docs for EnumVariant {
298 fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> {
299 docs_from_ast(&*self.source(db).1)
300 }
301}
302
284#[derive(Debug, Clone, PartialEq, Eq, Hash)] 303#[derive(Debug, Clone, PartialEq, Eq, Hash)]
285pub struct Function { 304pub struct Function {
286 pub(crate) def_id: DefId, 305 pub(crate) def_id: DefId,
@@ -352,19 +371,11 @@ impl Function {
352 pub fn generic_params(&self, db: &impl HirDatabase) -> Arc<GenericParams> { 371 pub fn generic_params(&self, db: &impl HirDatabase) -> Arc<GenericParams> {
353 db.generic_params(self.def_id) 372 db.generic_params(self.def_id)
354 } 373 }
374}
355 375
356 pub fn docs(&self, db: &impl HirDatabase) -> Option<String> { 376impl Docs for Function {
357 let def_loc = self.def_id.loc(db); 377 fn docs(&self, db: &impl HirDatabase) -> Option<Documentation> {
358 let syntax = db.file_item(def_loc.source_item_id); 378 docs_from_ast(&*self.source(db).1)
359 let fn_def = ast::FnDef::cast(&syntax).expect("fn def should point to FnDef node");
360
361 // doc_comment_text unconditionally returns a String
362 let comments = fn_def.doc_comment_text();
363 if comments.is_empty() {
364 None
365 } else {
366 Some(comments)
367 }
368 } 379 }
369} 380}
370 381
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 @@
1use ra_syntax::ast;
2
3use crate::HirDatabase;
4
5#[derive(Debug, Clone)]
6pub struct Documentation(String);
7
8impl Documentation {
9 pub fn new(s: &str) -> Self {
10 Self(s.into())
11 }
12
13 pub fn contents(&self) -> &str {
14 &self.0
15 }
16}
17
18impl Into<String> for Documentation {
19 fn into(self) -> String {
20 self.contents().into()
21 }
22}
23
24pub trait Docs {
25 fn docs(&self, db: &impl HirDatabase) -> Option<Documentation>;
26}
27
28pub(crate) fn docs_from_ast(node: &impl ast::DocCommentsOwner) -> Option<Documentation> {
29 let comments = node.doc_comment_text();
30 if comments.is_empty() {
31 None
32 } else {
33 Some(Documentation::new(&comments))
34 }
35}
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;
23mod impl_block; 23mod impl_block;
24mod expr; 24mod expr;
25mod generics; 25mod generics;
26mod docs;
26 27
27mod code_model_api; 28mod code_model_api;
28mod code_model_impl; 29mod code_model_impl;
@@ -45,6 +46,7 @@ pub use self::{
45 ty::Ty, 46 ty::Ty,
46 impl_block::{ImplBlock, ImplItem}, 47 impl_block::{ImplBlock, ImplItem},
47 code_model_impl::function::{FnScopes, ScopesWithSyntaxMapping}, 48 code_model_impl::function::{FnScopes, ScopesWithSyntaxMapping},
49 docs::{Docs, Documentation}
48}; 50};
49 51
50pub use self::code_model_api::{ 52pub use self::code_model_api::{
diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs
index 6bed299d2..aeb226847 100644
--- a/crates/ra_ide_api/src/completion/complete_path.rs
+++ b/crates/ra_ide_api/src/completion/complete_path.rs
@@ -2,6 +2,8 @@ use crate::{
2 completion::{CompletionItem, CompletionItemKind, Completions, CompletionKind, CompletionContext}, 2 completion::{CompletionItem, CompletionItemKind, Completions, CompletionKind, CompletionContext},
3}; 3};
4 4
5use hir::Docs;
6
5pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { 7pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
6 let (path, module) = match (&ctx.path_prefix, &ctx.module) { 8 let (path, module) = match (&ctx.path_prefix, &ctx.module) {
7 (Some(path), Some(module)) => (path.clone(), module), 9 (Some(path), Some(module)) => (path.clone(), module),
@@ -27,13 +29,14 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
27 hir::Def::Enum(e) => { 29 hir::Def::Enum(e) => {
28 e.variants(ctx.db) 30 e.variants(ctx.db)
29 .into_iter() 31 .into_iter()
30 .for_each(|(variant_name, _variant)| { 32 .for_each(|(variant_name, variant)| {
31 CompletionItem::new( 33 CompletionItem::new(
32 CompletionKind::Reference, 34 CompletionKind::Reference,
33 ctx.source_range(), 35 ctx.source_range(),
34 variant_name.to_string(), 36 variant_name.to_string(),
35 ) 37 )
36 .kind(CompletionItemKind::EnumVariant) 38 .kind(CompletionItemKind::EnumVariant)
39 .set_documentation(variant.docs(ctx.db))
37 .add_to(acc) 40 .add_to(acc)
38 }); 41 });
39 } 42 }
diff --git a/crates/ra_ide_api/src/completion/completion_item.rs b/crates/ra_ide_api/src/completion/completion_item.rs
index e3bf82304..8e0be4c4b 100644
--- a/crates/ra_ide_api/src/completion/completion_item.rs
+++ b/crates/ra_ide_api/src/completion/completion_item.rs
@@ -1,4 +1,4 @@
1use hir::PerNs; 1use hir::{Docs, Documentation, PerNs};
2 2
3use crate::completion::completion_context::CompletionContext; 3use crate::completion::completion_context::CompletionContext;
4use ra_syntax::{ 4use ra_syntax::{
@@ -19,7 +19,7 @@ pub struct CompletionItem {
19 label: String, 19 label: String,
20 kind: Option<CompletionItemKind>, 20 kind: Option<CompletionItemKind>,
21 detail: Option<String>, 21 detail: Option<String>,
22 documentation: Option<String>, 22 documentation: Option<Documentation>,
23 lookup: Option<String>, 23 lookup: Option<String>,
24 insert_text: Option<String>, 24 insert_text: Option<String>,
25 insert_text_format: InsertTextFormat, 25 insert_text_format: InsertTextFormat,
@@ -98,7 +98,7 @@ impl CompletionItem {
98 } 98 }
99 /// A doc-comment 99 /// A doc-comment
100 pub fn documentation(&self) -> Option<&str> { 100 pub fn documentation(&self) -> Option<&str> {
101 self.documentation.as_ref().map(|it| it.as_str()) 101 self.documentation.as_ref().map(|it| it.contents())
102 } 102 }
103 /// What string is used for filtering. 103 /// What string is used for filtering.
104 pub fn lookup(&self) -> &str { 104 pub fn lookup(&self) -> &str {
@@ -137,7 +137,7 @@ pub(crate) struct Builder {
137 insert_text: Option<String>, 137 insert_text: Option<String>,
138 insert_text_format: InsertTextFormat, 138 insert_text_format: InsertTextFormat,
139 detail: Option<String>, 139 detail: Option<String>,
140 documentation: Option<String>, 140 documentation: Option<Documentation>,
141 lookup: Option<String>, 141 lookup: Option<String>,
142 kind: Option<CompletionItemKind>, 142 kind: Option<CompletionItemKind>,
143 text_edit: Option<TextEdit>, 143 text_edit: Option<TextEdit>,
@@ -197,10 +197,10 @@ impl Builder {
197 self 197 self
198 } 198 }
199 #[allow(unused)] 199 #[allow(unused)]
200 pub(crate) fn documentation(self, docs: impl Into<String>) -> Builder { 200 pub(crate) fn documentation(self, docs: Documentation) -> Builder {
201 self.set_documentation(Some(docs)) 201 self.set_documentation(Some(docs))
202 } 202 }
203 pub(crate) fn set_documentation(mut self, docs: Option<impl Into<String>>) -> Builder { 203 pub(crate) fn set_documentation(mut self, docs: Option<Documentation>) -> Builder {
204 self.documentation = docs.map(Into::into); 204 self.documentation = docs.map(Into::into);
205 self 205 self
206 } 206 }
@@ -265,6 +265,7 @@ impl Builder {
265 } 265 }
266 self.insert_text_format = InsertTextFormat::Snippet; 266 self.insert_text_format = InsertTextFormat::Snippet;
267 } 267 }
268
268 if let Some(docs) = function.docs(ctx.db) { 269 if let Some(docs) = function.docs(ctx.db) {
269 self.documentation = Some(docs); 270 self.documentation = Some(docs);
270 } 271 }