Change DocFragments from enum variant fields to structs with a nested enum
This makes the code a lot easier to work with. It also makes it easier to add new fields without updating each variant and `match` individually. - Name the `Kind` variant after `DocFragmentKind` from `collapse_docs` - Remove unneeded impls
This commit is contained in:
parent
782013564e
commit
5f76b95e9b
@ -370,32 +370,22 @@ impl<I: IntoIterator<Item = ast::NestedMetaItem>> NestedAttributesExt for I {
|
||||
/// information can be given when a doctest fails. Sugared doc comments and "raw" doc comments are
|
||||
/// kept separate because of issue #42760.
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub enum DocFragment {
|
||||
/// A doc fragment created from a `///` or `//!` doc comment.
|
||||
SugaredDoc(usize, rustc_span::Span, String),
|
||||
/// A doc fragment created from a "raw" `#[doc=""]` attribute.
|
||||
RawDoc(usize, rustc_span::Span, String),
|
||||
/// A doc fragment created from a `#[doc(include="filename")]` attribute. Contains both the
|
||||
/// given filename and the file contents.
|
||||
Include(usize, rustc_span::Span, String, String),
|
||||
pub struct DocFragment {
|
||||
pub line: usize,
|
||||
pub span: rustc_span::Span,
|
||||
pub doc: String,
|
||||
pub kind: DocFragmentKind,
|
||||
}
|
||||
|
||||
impl DocFragment {
|
||||
pub fn as_str(&self) -> &str {
|
||||
match *self {
|
||||
DocFragment::SugaredDoc(_, _, ref s) => &s[..],
|
||||
DocFragment::RawDoc(_, _, ref s) => &s[..],
|
||||
DocFragment::Include(_, _, _, ref s) => &s[..],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn span(&self) -> rustc_span::Span {
|
||||
match *self {
|
||||
DocFragment::SugaredDoc(_, span, _)
|
||||
| DocFragment::RawDoc(_, span, _)
|
||||
| DocFragment::Include(_, span, _, _) => span,
|
||||
}
|
||||
}
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub enum DocFragmentKind {
|
||||
/// A doc fragment created from a `///` or `//!` doc comment.
|
||||
SugaredDoc,
|
||||
/// A doc fragment created from a "raw" `#[doc=""]` attribute.
|
||||
RawDoc,
|
||||
/// A doc fragment created from a `#[doc(include="filename")]` attribute. Contains both the
|
||||
/// given filename and the file contents.
|
||||
Include { filename: String },
|
||||
}
|
||||
|
||||
impl<'a> FromIterator<&'a DocFragment> for String {
|
||||
@ -407,12 +397,7 @@ impl<'a> FromIterator<&'a DocFragment> for String {
|
||||
if !acc.is_empty() {
|
||||
acc.push('\n');
|
||||
}
|
||||
match *frag {
|
||||
DocFragment::SugaredDoc(_, _, ref docs)
|
||||
| DocFragment::RawDoc(_, _, ref docs)
|
||||
| DocFragment::Include(_, _, _, ref docs) => acc.push_str(docs),
|
||||
}
|
||||
|
||||
acc.push_str(&frag.doc);
|
||||
acc
|
||||
})
|
||||
}
|
||||
@ -547,15 +532,15 @@ impl Attributes {
|
||||
.filter_map(|attr| {
|
||||
if let Some(value) = attr.doc_str() {
|
||||
let value = beautify_doc_string(value);
|
||||
let mk_fragment: fn(_, _, _) -> _ = if attr.is_doc_comment() {
|
||||
DocFragment::SugaredDoc
|
||||
let kind = if attr.is_doc_comment() {
|
||||
DocFragmentKind::SugaredDoc
|
||||
} else {
|
||||
DocFragment::RawDoc
|
||||
DocFragmentKind::RawDoc
|
||||
};
|
||||
|
||||
let line = doc_line;
|
||||
doc_line += value.lines().count();
|
||||
doc_strings.push(mk_fragment(line, attr.span, value));
|
||||
doc_strings.push(DocFragment { line, span: attr.span, doc: value, kind });
|
||||
|
||||
if sp.is_none() {
|
||||
sp = Some(attr.span);
|
||||
@ -575,9 +560,12 @@ impl Attributes {
|
||||
{
|
||||
let line = doc_line;
|
||||
doc_line += contents.lines().count();
|
||||
doc_strings.push(DocFragment::Include(
|
||||
line, attr.span, filename, contents,
|
||||
));
|
||||
doc_strings.push(DocFragment {
|
||||
line,
|
||||
span: attr.span,
|
||||
doc: contents,
|
||||
kind: DocFragmentKind::Include { filename },
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -621,7 +609,7 @@ impl Attributes {
|
||||
/// Finds the `doc` attribute as a NameValue and returns the corresponding
|
||||
/// value found.
|
||||
pub fn doc_value(&self) -> Option<&str> {
|
||||
self.doc_strings.first().map(|s| s.as_str())
|
||||
self.doc_strings.first().map(|s| s.doc.as_str())
|
||||
}
|
||||
|
||||
/// Finds all `doc` attributes as NameValues and returns their corresponding values, joined
|
||||
|
@ -232,7 +232,12 @@ impl fold::DocFolder for CoverageCalculator {
|
||||
let mut tests = Tests { found_tests: 0 };
|
||||
|
||||
find_testable_code(
|
||||
&i.attrs.doc_strings.iter().map(|d| d.as_str()).collect::<Vec<_>>().join("\n"),
|
||||
&i.attrs
|
||||
.doc_strings
|
||||
.iter()
|
||||
.map(|d| d.doc.as_str())
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n"),
|
||||
&mut tests,
|
||||
ErrorCodes::No,
|
||||
false,
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::clean::{self, DocFragment, Item};
|
||||
use crate::clean::{self, DocFragment, DocFragmentKind, Item};
|
||||
use crate::core::DocContext;
|
||||
use crate::fold;
|
||||
use crate::fold::DocFolder;
|
||||
@ -12,23 +12,6 @@ pub const COLLAPSE_DOCS: Pass = Pass {
|
||||
description: "concatenates all document attributes into one document attribute",
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
enum DocFragmentKind {
|
||||
Sugared,
|
||||
Raw,
|
||||
Include,
|
||||
}
|
||||
|
||||
impl DocFragment {
|
||||
fn kind(&self) -> DocFragmentKind {
|
||||
match *self {
|
||||
DocFragment::SugaredDoc(..) => DocFragmentKind::Sugared,
|
||||
DocFragment::RawDoc(..) => DocFragmentKind::Raw,
|
||||
DocFragment::Include(..) => DocFragmentKind::Include,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn collapse_docs(krate: clean::Crate, _: &DocContext<'_>) -> clean::Crate {
|
||||
let mut krate = Collapser.fold_crate(krate);
|
||||
krate.collapsed = true;
|
||||
@ -50,30 +33,22 @@ fn collapse(doc_strings: &mut Vec<DocFragment>) {
|
||||
|
||||
for frag in take(doc_strings) {
|
||||
if let Some(mut curr_frag) = last_frag.take() {
|
||||
let curr_kind = curr_frag.kind();
|
||||
let new_kind = frag.kind();
|
||||
let curr_kind = &curr_frag.kind;
|
||||
let new_kind = &frag.kind;
|
||||
|
||||
if curr_kind == DocFragmentKind::Include || curr_kind != new_kind {
|
||||
match curr_frag {
|
||||
DocFragment::SugaredDoc(_, _, ref mut doc_string)
|
||||
| DocFragment::RawDoc(_, _, ref mut doc_string) => {
|
||||
// add a newline for extra padding between segments
|
||||
doc_string.push('\n');
|
||||
}
|
||||
_ => {}
|
||||
if matches!(*curr_kind, DocFragmentKind::Include { .. }) || curr_kind != new_kind {
|
||||
if *curr_kind == DocFragmentKind::SugaredDoc
|
||||
|| *curr_kind == DocFragmentKind::RawDoc
|
||||
{
|
||||
// add a newline for extra padding between segments
|
||||
curr_frag.doc.push('\n');
|
||||
}
|
||||
docs.push(curr_frag);
|
||||
last_frag = Some(frag);
|
||||
} else {
|
||||
match curr_frag {
|
||||
DocFragment::SugaredDoc(_, ref mut span, ref mut doc_string)
|
||||
| DocFragment::RawDoc(_, ref mut span, ref mut doc_string) => {
|
||||
doc_string.push('\n');
|
||||
doc_string.push_str(frag.as_str());
|
||||
*span = span.to(frag.span());
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
curr_frag.doc.push('\n');
|
||||
curr_frag.doc.push_str(&frag.doc);
|
||||
curr_frag.span = curr_frag.span.to(frag.span);
|
||||
last_frag = Some(curr_frag);
|
||||
}
|
||||
} else {
|
||||
|
@ -8,7 +8,7 @@ use std::mem;
|
||||
use std::ops::Range;
|
||||
|
||||
use self::Condition::*;
|
||||
use crate::clean::{self, GetDefId, Item};
|
||||
use crate::clean::{self, DocFragmentKind, GetDefId, Item};
|
||||
use crate::core::DocContext;
|
||||
use crate::fold::{DocFolder, StripItem};
|
||||
|
||||
@ -314,11 +314,11 @@ crate fn span_of_attrs(attrs: &clean::Attributes) -> Option<Span> {
|
||||
if attrs.doc_strings.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let start = attrs.doc_strings[0].span();
|
||||
let start = attrs.doc_strings[0].span;
|
||||
if start == DUMMY_SP {
|
||||
return None;
|
||||
}
|
||||
let end = attrs.doc_strings.last().expect("no doc strings provided").span();
|
||||
let end = attrs.doc_strings.last().expect("no doc strings provided").span;
|
||||
Some(start.to(end))
|
||||
}
|
||||
|
||||
@ -333,10 +333,8 @@ crate fn source_span_for_markdown_range(
|
||||
md_range: &Range<usize>,
|
||||
attrs: &clean::Attributes,
|
||||
) -> Option<Span> {
|
||||
let is_all_sugared_doc = attrs.doc_strings.iter().all(|frag| match frag {
|
||||
clean::DocFragment::SugaredDoc(..) => true,
|
||||
_ => false,
|
||||
});
|
||||
let is_all_sugared_doc =
|
||||
attrs.doc_strings.iter().all(|frag| frag.kind == DocFragmentKind::SugaredDoc);
|
||||
|
||||
if !is_all_sugared_doc {
|
||||
return None;
|
||||
|
@ -36,13 +36,7 @@ impl clean::Attributes {
|
||||
|
||||
fn unindent_fragments(docs: &mut Vec<DocFragment>) {
|
||||
for fragment in docs {
|
||||
match *fragment {
|
||||
DocFragment::SugaredDoc(_, _, ref mut doc_string)
|
||||
| DocFragment::RawDoc(_, _, ref mut doc_string)
|
||||
| DocFragment::Include(_, _, _, ref mut doc_string) => {
|
||||
*doc_string = unindent(doc_string)
|
||||
}
|
||||
}
|
||||
fragment.doc = unindent(&fragment.doc);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user