aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/docs.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-06-03 12:05:52 +0100
committerGitHub <[email protected]>2020-06-03 12:05:52 +0100
commitc6b739bad0c0a458d3ae6bb2bc4514477f325e31 (patch)
tree6083eb9eb766a61b6d71154f1e345c461ebdbc7c /crates/ra_hir_def/src/docs.rs
parenta36c1d3fbcfe0837b73d5a849111683bef447fd8 (diff)
parented866892640214d315d3e9503ccaed96ca87ccc0 (diff)
Merge #4660
4660: Enable hover and autocomplete docs on macro generated items r=aloucks a=aloucks Enable hover and autocomplete docs on macro generated items. This de-sugars doc comments into `doc` attributes in some cases, but not all. Comments and `doc` attributes are then merged together. This PR is essentially a partial implementation of what's being suggested #3182, but it's not all the way there yet. ~I still need to add unit tests~, but I wanted to first get feedback on whether or not this was an acceptable path forward. Fixes #4564 Fixes #3984 Fixes #3180 Related #3182 ![macro_item_docs](https://user-images.githubusercontent.com/221559/83336760-15012200-a284-11ea-8d0d-b6a615850044.gif) Co-authored-by: Aaron Loucks <[email protected]>
Diffstat (limited to 'crates/ra_hir_def/src/docs.rs')
-rw-r--r--crates/ra_hir_def/src/docs.rs50
1 files changed, 48 insertions, 2 deletions
diff --git a/crates/ra_hir_def/src/docs.rs b/crates/ra_hir_def/src/docs.rs
index b221ae1ce..2630b3d89 100644
--- a/crates/ra_hir_def/src/docs.rs
+++ b/crates/ra_hir_def/src/docs.rs
@@ -29,6 +29,13 @@ impl Documentation {
29 Documentation(s.into()) 29 Documentation(s.into())
30 } 30 }
31 31
32 pub fn from_ast<N>(node: &N) -> Option<Documentation>
33 where
34 N: ast::DocCommentsOwner + ast::AttrsOwner,
35 {
36 docs_from_ast(node)
37 }
38
32 pub fn as_str(&self) -> &str { 39 pub fn as_str(&self) -> &str {
33 &*self.0 40 &*self.0
34 } 41 }
@@ -70,6 +77,45 @@ impl Documentation {
70 } 77 }
71} 78}
72 79
73pub(crate) fn docs_from_ast(node: &impl ast::DocCommentsOwner) -> Option<Documentation> { 80pub(crate) fn docs_from_ast<N>(node: &N) -> Option<Documentation>
74 node.doc_comment_text().map(|it| Documentation::new(&it)) 81where
82 N: ast::DocCommentsOwner + ast::AttrsOwner,
83{
84 let doc_comment_text = node.doc_comment_text();
85 let doc_attr_text = expand_doc_attrs(node);
86 let docs = merge_doc_comments_and_attrs(doc_comment_text, doc_attr_text);
87 docs.map(|it| Documentation::new(&it))
88}
89
90fn merge_doc_comments_and_attrs(
91 doc_comment_text: Option<String>,
92 doc_attr_text: Option<String>,
93) -> Option<String> {
94 match (doc_comment_text, doc_attr_text) {
95 (Some(mut comment_text), Some(attr_text)) => {
96 comment_text.push_str("\n\n");
97 comment_text.push_str(&attr_text);
98 Some(comment_text)
99 }
100 (Some(comment_text), None) => Some(comment_text),
101 (None, Some(attr_text)) => Some(attr_text),
102 (None, None) => None,
103 }
104}
105
106fn expand_doc_attrs(owner: &dyn ast::AttrsOwner) -> Option<String> {
107 let mut docs = String::new();
108 for attr in owner.attrs() {
109 if let Some(("doc", value)) =
110 attr.as_simple_key_value().as_ref().map(|(k, v)| (k.as_str(), v.as_str()))
111 {
112 docs.push_str(value);
113 docs.push_str("\n\n");
114 }
115 }
116 if docs.is_empty() {
117 None
118 } else {
119 Some(docs.trim_end_matches("\n\n").to_owned())
120 }
75} 121}