]> git.lizzy.rs Git - rust.git/blob - src/librustdoc/passes/collapse_docs.rs
Auto merge of #78068 - RalfJung:union-safe-assign, r=nikomatsakis
[rust.git] / src / librustdoc / passes / collapse_docs.rs
1 use crate::clean::{self, DocFragment, DocFragmentKind, 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 crate 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 crate fn collapse_docs(krate: clean::Crate, _: &DocContext<'_>) -> clean::Crate {
16     let mut krate = Collapser.fold_crate(krate);
17     krate.collapsed = true;
18     krate
19 }
20
21 struct Collapser;
22
23 impl fold::DocFolder for Collapser {
24     fn fold_item(&mut self, mut i: Item) -> Option<Item> {
25         i.attrs.collapse_doc_comments();
26         Some(self.fold_item_recur(i))
27     }
28 }
29
30 fn collapse(doc_strings: &mut Vec<DocFragment>) {
31     let mut docs = vec![];
32     let mut last_frag: Option<DocFragment> = None;
33
34     for frag in take(doc_strings) {
35         if let Some(mut curr_frag) = last_frag.take() {
36             let curr_kind = &curr_frag.kind;
37             let new_kind = &frag.kind;
38
39             if matches!(*curr_kind, DocFragmentKind::Include { .. })
40                 || curr_kind != new_kind
41                 || curr_frag.parent_module != frag.parent_module
42             {
43                 if *curr_kind == DocFragmentKind::SugaredDoc
44                     || *curr_kind == DocFragmentKind::RawDoc
45                 {
46                     // add a newline for extra padding between segments
47                     curr_frag.doc.push('\n');
48                 }
49                 docs.push(curr_frag);
50                 last_frag = Some(frag);
51             } else {
52                 curr_frag.doc.push('\n');
53                 curr_frag.doc.push_str(&frag.doc);
54                 curr_frag.span = curr_frag.span.to(frag.span);
55                 last_frag = Some(curr_frag);
56             }
57         } else {
58             last_frag = Some(frag);
59         }
60     }
61
62     if let Some(frag) = last_frag.take() {
63         docs.push(frag);
64     }
65     *doc_strings = docs;
66 }
67
68 impl clean::Attributes {
69     crate fn collapse_doc_comments(&mut self) {
70         collapse(&mut self.doc_strings);
71     }
72 }