aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/docs.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/docs.rs')
-rw-r--r--crates/hir_def/src/docs.rs121
1 files changed, 0 insertions, 121 deletions
diff --git a/crates/hir_def/src/docs.rs b/crates/hir_def/src/docs.rs
deleted file mode 100644
index 3e59a8f47..000000000
--- a/crates/hir_def/src/docs.rs
+++ /dev/null
@@ -1,121 +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 either::Either;
9use itertools::Itertools;
10use syntax::{ast, SmolStr};
11
12use crate::{
13 db::DefDatabase,
14 src::{HasChildSource, HasSource},
15 AdtId, AttrDefId, Lookup,
16};
17
18/// Holds documentation
19#[derive(Debug, Clone, PartialEq, Eq)]
20pub struct Documentation(Arc<str>);
21
22impl Into<String> for Documentation {
23 fn into(self) -> String {
24 self.as_str().to_owned()
25 }
26}
27
28impl Documentation {
29 fn new(s: &str) -> Documentation {
30 Documentation(s.into())
31 }
32
33 pub fn from_ast<N>(node: &N) -> Option<Documentation>
34 where
35 N: ast::DocCommentsOwner + ast::AttrsOwner,
36 {
37 docs_from_ast(node)
38 }
39
40 pub fn as_str(&self) -> &str {
41 &*self.0
42 }
43
44 pub(crate) fn documentation_query(
45 db: &dyn DefDatabase,
46 def: AttrDefId,
47 ) -> Option<Documentation> {
48 match def {
49 AttrDefId::ModuleId(module) => {
50 let def_map = db.crate_def_map(module.krate);
51 let src = def_map[module.local_id].declaration_source(db)?;
52 docs_from_ast(&src.value)
53 }
54 AttrDefId::FieldId(it) => {
55 let src = it.parent.child_source(db);
56 match &src.value[it.local_id] {
57 Either::Left(_tuple) => None,
58 Either::Right(record) => docs_from_ast(record),
59 }
60 }
61 AttrDefId::AdtId(it) => match it {
62 AdtId::StructId(it) => docs_from_ast(&it.lookup(db).source(db).value),
63 AdtId::EnumId(it) => docs_from_ast(&it.lookup(db).source(db).value),
64 AdtId::UnionId(it) => docs_from_ast(&it.lookup(db).source(db).value),
65 },
66 AttrDefId::EnumVariantId(it) => {
67 let src = it.parent.child_source(db);
68 docs_from_ast(&src.value[it.local_id])
69 }
70 AttrDefId::TraitId(it) => docs_from_ast(&it.lookup(db).source(db).value),
71 AttrDefId::MacroDefId(it) => docs_from_ast(&it.ast_id?.to_node(db.upcast())),
72 AttrDefId::ConstId(it) => docs_from_ast(&it.lookup(db).source(db).value),
73 AttrDefId::StaticId(it) => docs_from_ast(&it.lookup(db).source(db).value),
74 AttrDefId::FunctionId(it) => docs_from_ast(&it.lookup(db).source(db).value),
75 AttrDefId::TypeAliasId(it) => docs_from_ast(&it.lookup(db).source(db).value),
76 AttrDefId::ImplId(_) => None,
77 }
78 }
79}
80
81pub(crate) fn docs_from_ast<N>(node: &N) -> Option<Documentation>
82where
83 N: ast::DocCommentsOwner + ast::AttrsOwner,
84{
85 let doc_comment_text = node.doc_comment_text();
86 let doc_attr_text = expand_doc_attrs(node);
87 let docs = merge_doc_comments_and_attrs(doc_comment_text, doc_attr_text);
88 docs.map(|it| Documentation::new(&it))
89}
90
91fn merge_doc_comments_and_attrs(
92 doc_comment_text: Option<String>,
93 doc_attr_text: Option<String>,
94) -> Option<String> {
95 match (doc_comment_text, doc_attr_text) {
96 (Some(mut comment_text), Some(attr_text)) => {
97 comment_text.push_str("\n");
98 comment_text.push_str(&attr_text);
99 Some(comment_text)
100 }
101 (Some(comment_text), None) => Some(comment_text),
102 (None, Some(attr_text)) => Some(attr_text),
103 (None, None) => None,
104 }
105}
106
107fn expand_doc_attrs(owner: &dyn ast::AttrsOwner) -> Option<String> {
108 let mut docs = String::new();
109 owner
110 .attrs()
111 .filter_map(|attr| attr.as_simple_key_value().filter(|(key, _)| key == "doc"))
112 .map(|(_, value)| value)
113 .intersperse(SmolStr::new_inline("\n"))
114 // No FromIterator<SmolStr> for String
115 .for_each(|s| docs.push_str(s.as_str()));
116 if docs.is_empty() {
117 None
118 } else {
119 Some(docs)
120 }
121}