aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def')
-rw-r--r--crates/ra_hir_def/src/attr.rs8
-rw-r--r--crates/ra_hir_def/src/docs.rs43
2 files changed, 48 insertions, 3 deletions
diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs
index 8b6c0bede..2eeba0572 100644
--- a/crates/ra_hir_def/src/attr.rs
+++ b/crates/ra_hir_def/src/attr.rs
@@ -87,12 +87,18 @@ impl Attrs {
87 } 87 }
88 88
89 pub(crate) fn new(owner: &dyn AttrsOwner, hygiene: &Hygiene) -> Attrs { 89 pub(crate) fn new(owner: &dyn AttrsOwner, hygiene: &Hygiene) -> Attrs {
90 let docs = ast::CommentIter::from_syntax_node(owner.syntax()).doc_comment_text().map(
91 |docs_text| Attr {
92 input: Some(AttrInput::Literal(SmolStr::new(docs_text))),
93 path: ModPath::from(hir_expand::name!(doc)),
94 },
95 );
90 let mut attrs = owner.attrs().peekable(); 96 let mut attrs = owner.attrs().peekable();
91 let entries = if attrs.peek().is_none() { 97 let entries = if attrs.peek().is_none() {
92 // Avoid heap allocation 98 // Avoid heap allocation
93 None 99 None
94 } else { 100 } else {
95 Some(attrs.flat_map(|ast| Attr::from_src(ast, hygiene)).collect()) 101 Some(attrs.flat_map(|ast| Attr::from_src(ast, hygiene)).chain(docs).collect())
96 }; 102 };
97 Attrs { entries } 103 Attrs { entries }
98 } 104 }
diff --git a/crates/ra_hir_def/src/docs.rs b/crates/ra_hir_def/src/docs.rs
index b221ae1ce..74b9f8199 100644
--- a/crates/ra_hir_def/src/docs.rs
+++ b/crates/ra_hir_def/src/docs.rs
@@ -70,6 +70,45 @@ impl Documentation {
70 } 70 }
71} 71}
72 72
73pub(crate) fn docs_from_ast(node: &impl ast::DocCommentsOwner) -> Option<Documentation> { 73pub(crate) fn docs_from_ast<N>(node: &N) -> Option<Documentation>
74 node.doc_comment_text().map(|it| Documentation::new(&it)) 74where
75 N: ast::DocCommentsOwner + ast::AttrsOwner,
76{
77 let doc_comment_text = node.doc_comment_text();
78 let doc_attr_text = expand_doc_attrs(node);
79 let docs = merge_doc_comments_and_attrs(doc_comment_text, doc_attr_text);
80 docs.map(|it| Documentation::new(&it))
81}
82
83fn merge_doc_comments_and_attrs(
84 doc_comment_text: Option<String>,
85 doc_attr_text: Option<String>,
86) -> Option<String> {
87 match (doc_comment_text, doc_attr_text) {
88 (Some(mut comment_text), Some(attr_text)) => {
89 comment_text.push_str("\n\n");
90 comment_text.push_str(&attr_text);
91 Some(comment_text)
92 }
93 (Some(comment_text), None) => Some(comment_text),
94 (None, Some(attr_text)) => Some(attr_text),
95 (None, None) => None,
96 }
97}
98
99fn expand_doc_attrs(owner: &dyn ast::AttrsOwner) -> Option<String> {
100 let mut docs = String::new();
101 for attr in owner.attrs() {
102 if let Some(("doc", value)) =
103 attr.as_simple_key_value().as_ref().map(|(k, v)| (k.as_str(), v.as_str()))
104 {
105 docs.push_str(value);
106 docs.push_str("\n\n");
107 }
108 }
109 if docs.is_empty() {
110 None
111 } else {
112 Some(docs)
113 }
75} 114}