]> git.lizzy.rs Git - rust.git/blob - src/librustdoc/passes/collapse_docs.rs
Auto merge of #69421 - flip1995:clippyup, r=Dylan-DPC
[rust.git] / src / librustdoc / passes / collapse_docs.rs
1 use crate::clean::{self, DocFragment, Item};
2 use crate::core::DocContext;
3 use crate::fold;
4 use crate::fold::DocFolder;
5 use crate::passes::Pass;
6
7 use std::mem::take;
8
9 pub const COLLAPSE_DOCS: Pass = Pass {
10     name: "collapse-docs",
11     run: collapse_docs,
12     description: "concatenates all document attributes into one document attribute",
13 };
14
15 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
16 enum DocFragmentKind {
17     Sugared,
18     Raw,
19     Include,
20 }
21
22 impl DocFragment {
23     fn kind(&self) -> DocFragmentKind {
24         match *self {
25             DocFragment::SugaredDoc(..) => DocFragmentKind::Sugared,
26             DocFragment::RawDoc(..) => DocFragmentKind::Raw,
27             DocFragment::Include(..) => DocFragmentKind::Include,
28         }
29     }
30 }
31
32 pub fn collapse_docs(krate: clean::Crate, _: &DocContext<'_>) -> clean::Crate {
33     let mut krate = Collapser.fold_crate(krate);
34     krate.collapsed = true;
35     krate
36 }
37
38 struct Collapser;
39
40 impl fold::DocFolder for Collapser {
41     fn fold_item(&mut self, mut i: Item) -> Option<Item> {
42         i.attrs.collapse_doc_comments();
43         self.fold_item_recur(i)
44     }
45 }
46
47 fn collapse(doc_strings: &mut Vec<DocFragment>) {
48     let mut docs = vec![];
49     let mut last_frag: Option<DocFragment> = None;
50
51     for frag in take(doc_strings) {
52         if let Some(mut curr_frag) = last_frag.take() {
53             let curr_kind = curr_frag.kind();
54             let new_kind = frag.kind();
55
56             if curr_kind == DocFragmentKind::Include || curr_kind != new_kind {
57                 match curr_frag {
58                     DocFragment::SugaredDoc(_, _, ref mut doc_string)
59                     | DocFragment::RawDoc(_, _, ref mut doc_string) => {
60                         // add a newline for extra padding between segments
61                         doc_string.push('\n');
62                     }
63                     _ => {}
64                 }
65                 docs.push(curr_frag);
66                 last_frag = Some(frag);
67             } else {
68                 match curr_frag {
69                     DocFragment::SugaredDoc(_, ref mut span, ref mut doc_string)
70                     | DocFragment::RawDoc(_, ref mut span, ref mut doc_string) => {
71                         doc_string.push('\n');
72                         doc_string.push_str(frag.as_str());
73                         *span = span.to(frag.span());
74                     }
75                     _ => unreachable!(),
76                 }
77                 last_frag = Some(curr_frag);
78             }
79         } else {
80             last_frag = Some(frag);
81         }
82     }
83
84     if let Some(frag) = last_frag.take() {
85         docs.push(frag);
86     }
87     *doc_strings = docs;
88 }
89
90 impl clean::Attributes {
91     pub fn collapse_doc_comments(&mut self) {
92         collapse(&mut self.doc_strings);
93     }
94 }