]> git.lizzy.rs Git - rust.git/blob - crates/ra_hir_def/src/docs.rs
Replace `ra_hir_expand::either` with crate
[rust.git] / crates / ra_hir_def / src / docs.rs
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
6 use std::sync::Arc;
7
8 use either::Either;
9 use ra_syntax::ast;
10
11 use crate::{
12     db::DefDatabase,
13     src::{HasChildSource, HasSource},
14     AdtId, AstItemDef, AttrDefId, Lookup,
15 };
16
17 /// Holds documentation
18 #[derive(Debug, Clone, PartialEq, Eq)]
19 pub struct Documentation(Arc<str>);
20
21 impl Into<String> for Documentation {
22     fn into(self) -> String {
23         self.as_str().to_owned()
24     }
25 }
26
27 impl Documentation {
28     fn new(s: &str) -> Documentation {
29         Documentation(s.into())
30     }
31
32     pub fn as_str(&self) -> &str {
33         &*self.0
34     }
35
36     pub(crate) fn documentation_query(
37         db: &impl DefDatabase,
38         def: AttrDefId,
39     ) -> Option<Documentation> {
40         match def {
41             AttrDefId::ModuleId(module) => {
42                 let def_map = db.crate_def_map(module.krate);
43                 let src = def_map[module.local_id].declaration_source(db)?;
44                 docs_from_ast(&src.value)
45             }
46             AttrDefId::StructFieldId(it) => {
47                 let src = it.parent.child_source(db);
48                 match &src.value[it.local_id] {
49                     Either::Left(_tuple) => None,
50                     Either::Right(record) => docs_from_ast(record),
51                 }
52             }
53             AttrDefId::AdtId(it) => match it {
54                 AdtId::StructId(it) => docs_from_ast(&it.source(db).value),
55                 AdtId::EnumId(it) => docs_from_ast(&it.source(db).value),
56                 AdtId::UnionId(it) => docs_from_ast(&it.source(db).value),
57             },
58             AttrDefId::EnumVariantId(it) => {
59                 let src = it.parent.child_source(db);
60                 docs_from_ast(&src.value[it.local_id])
61             }
62             AttrDefId::TraitId(it) => docs_from_ast(&it.source(db).value),
63             AttrDefId::MacroDefId(it) => docs_from_ast(&it.ast_id.to_node(db)),
64             AttrDefId::ConstId(it) => docs_from_ast(&it.lookup(db).source(db).value),
65             AttrDefId::StaticId(it) => docs_from_ast(&it.lookup(db).source(db).value),
66             AttrDefId::FunctionId(it) => docs_from_ast(&it.lookup(db).source(db).value),
67             AttrDefId::TypeAliasId(it) => docs_from_ast(&it.lookup(db).source(db).value),
68             AttrDefId::ImplId(_) => None,
69         }
70     }
71 }
72
73 pub(crate) fn docs_from_ast(node: &impl ast::DocCommentsOwner) -> Option<Documentation> {
74     node.doc_comment_text().map(|it| Documentation::new(&it))
75 }