aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src')
-rw-r--r--crates/hir_def/src/attr.rs25
-rw-r--r--crates/hir_def/src/docs.rs79
-rw-r--r--crates/hir_def/src/lib.rs1
3 files changed, 22 insertions, 83 deletions
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs
index 7825290e6..98293aad3 100644
--- a/crates/hir_def/src/attr.rs
+++ b/crates/hir_def/src/attr.rs
@@ -15,7 +15,6 @@ use tt::Subtree;
15 15
16use crate::{ 16use crate::{
17 db::DefDatabase, 17 db::DefDatabase,
18 docs::Documentation,
19 item_tree::{ItemTreeId, ItemTreeNode}, 18 item_tree::{ItemTreeId, ItemTreeNode},
20 nameres::ModuleSource, 19 nameres::ModuleSource,
21 path::ModPath, 20 path::ModPath,
@@ -23,6 +22,22 @@ use crate::{
23 AdtId, AttrDefId, Lookup, 22 AdtId, AttrDefId, Lookup,
24}; 23};
25 24
25/// Holds documentation
26#[derive(Debug, Clone, PartialEq, Eq)]
27pub struct Documentation(Arc<str>);
28
29impl Documentation {
30 pub fn as_str(&self) -> &str {
31 &self.0
32 }
33}
34
35impl Into<String> for Documentation {
36 fn into(self) -> String {
37 self.as_str().to_owned()
38 }
39}
40
26#[derive(Default, Debug, Clone, PartialEq, Eq)] 41#[derive(Default, Debug, Clone, PartialEq, Eq)]
27pub struct Attrs { 42pub struct Attrs {
28 entries: Option<Arc<[Attr]>>, 43 entries: Option<Arc<[Attr]>>,
@@ -102,7 +117,7 @@ impl Attrs {
102 }, 117 },
103 ); 118 );
104 let mut attrs = owner.attrs().peekable(); 119 let mut attrs = owner.attrs().peekable();
105 let entries = if attrs.peek().is_none() { 120 let entries = if attrs.peek().is_none() && docs.is_none() {
106 // Avoid heap allocation 121 // Avoid heap allocation
107 None 122 None
108 } else { 123 } else {
@@ -154,7 +169,11 @@ impl Attrs {
154 .intersperse(&SmolStr::new_inline("\n")) 169 .intersperse(&SmolStr::new_inline("\n"))
155 // No FromIterator<SmolStr> for String 170 // No FromIterator<SmolStr> for String
156 .for_each(|s| docs.push_str(s.as_str())); 171 .for_each(|s| docs.push_str(s.as_str()));
157 if docs.is_empty() { None } else { Some(docs) }.map(|it| Documentation::new(&it)) 172 if docs.is_empty() {
173 None
174 } else {
175 Some(Documentation(docs.into()))
176 }
158 } 177 }
159} 178}
160 179
diff --git a/crates/hir_def/src/docs.rs b/crates/hir_def/src/docs.rs
deleted file mode 100644
index 6a27effef..000000000
--- a/crates/hir_def/src/docs.rs
+++ /dev/null
@@ -1,79 +0,0 @@
1//! Defines hir documentation.
2//!
3//! This really shouldn't exist, instead, we should deshugar doc comments into attributes, see
4//! https://github.com/rust-analyzer/rust-analyzer/issues/2148#issuecomment-550519102
5
6use std::sync::Arc;
7
8use itertools::Itertools;
9use syntax::{ast, SmolStr};
10
11/// Holds documentation
12#[derive(Debug, Clone, PartialEq, Eq)]
13pub struct Documentation(Arc<str>);
14
15impl Into<String> for Documentation {
16 fn into(self) -> String {
17 self.as_str().to_owned()
18 }
19}
20
21impl Documentation {
22 pub fn new(s: &str) -> Documentation {
23 Documentation(s.into())
24 }
25
26 pub fn from_ast<N>(node: &N) -> Option<Documentation>
27 where
28 N: ast::DocCommentsOwner + ast::AttrsOwner,
29 {
30 docs_from_ast(node)
31 }
32
33 pub fn as_str(&self) -> &str {
34 &*self.0
35 }
36}
37
38pub(crate) fn docs_from_ast<N>(node: &N) -> Option<Documentation>
39where
40 N: ast::DocCommentsOwner + ast::AttrsOwner,
41{
42 let doc_comment_text = node.doc_comment_text();
43 let doc_attr_text = expand_doc_attrs(node);
44 let docs = merge_doc_comments_and_attrs(doc_comment_text, doc_attr_text);
45 docs.map(|it| Documentation::new(&it))
46}
47
48fn merge_doc_comments_and_attrs(
49 doc_comment_text: Option<String>,
50 doc_attr_text: Option<String>,
51) -> Option<String> {
52 match (doc_comment_text, doc_attr_text) {
53 (Some(mut comment_text), Some(attr_text)) => {
54 comment_text.reserve(attr_text.len() + 1);
55 comment_text.push('\n');
56 comment_text.push_str(&attr_text);
57 Some(comment_text)
58 }
59 (Some(comment_text), None) => Some(comment_text),
60 (None, Some(attr_text)) => Some(attr_text),
61 (None, None) => None,
62 }
63}
64
65fn expand_doc_attrs(owner: &dyn ast::AttrsOwner) -> Option<String> {
66 let mut docs = String::new();
67 owner
68 .attrs()
69 .filter_map(|attr| attr.as_simple_key_value().filter(|(key, _)| key == "doc"))
70 .map(|(_, value)| value)
71 .intersperse(SmolStr::new_inline("\n"))
72 // No FromIterator<SmolStr> for String
73 .for_each(|s| docs.push_str(s.as_str()));
74 if docs.is_empty() {
75 None
76 } else {
77 Some(docs)
78 }
79}
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs
index b41c5acb2..02ed30e4d 100644
--- a/crates/hir_def/src/lib.rs
+++ b/crates/hir_def/src/lib.rs
@@ -31,7 +31,6 @@ pub mod adt;
31pub mod data; 31pub mod data;
32pub mod generics; 32pub mod generics;
33pub mod lang_item; 33pub mod lang_item;
34pub mod docs;
35 34
36pub mod expr; 35pub mod expr;
37pub mod body; 36pub mod body;