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:
@@ -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
|
/// information can be given when a doctest fails. Sugared doc comments and "raw" doc comments are
|
||||||
/// kept separate because of issue #42760.
|
/// kept separate because of issue #42760.
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||||
pub enum DocFragment {
|
pub struct DocFragment {
|
||||||
/// A doc fragment created from a `///` or `//!` doc comment.
|
pub line: usize,
|
||||||
SugaredDoc(usize, rustc_span::Span, String),
|
pub span: rustc_span::Span,
|
||||||
/// A doc fragment created from a "raw" `#[doc=""]` attribute.
|
pub doc: String,
|
||||||
RawDoc(usize, rustc_span::Span, String),
|
pub kind: DocFragmentKind,
|
||||||
/// 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),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DocFragment {
|
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||||
pub fn as_str(&self) -> &str {
|
pub enum DocFragmentKind {
|
||||||
match *self {
|
/// A doc fragment created from a `///` or `//!` doc comment.
|
||||||
DocFragment::SugaredDoc(_, _, ref s) => &s[..],
|
SugaredDoc,
|
||||||
DocFragment::RawDoc(_, _, ref s) => &s[..],
|
/// A doc fragment created from a "raw" `#[doc=""]` attribute.
|
||||||
DocFragment::Include(_, _, _, ref s) => &s[..],
|
RawDoc,
|
||||||
}
|
/// A doc fragment created from a `#[doc(include="filename")]` attribute. Contains both the
|
||||||
}
|
/// given filename and the file contents.
|
||||||
|
Include { filename: String },
|
||||||
pub fn span(&self) -> rustc_span::Span {
|
|
||||||
match *self {
|
|
||||||
DocFragment::SugaredDoc(_, span, _)
|
|
||||||
| DocFragment::RawDoc(_, span, _)
|
|
||||||
| DocFragment::Include(_, span, _, _) => span,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FromIterator<&'a DocFragment> for String {
|
impl<'a> FromIterator<&'a DocFragment> for String {
|
||||||
@@ -407,12 +397,7 @@ impl<'a> FromIterator<&'a DocFragment> for String {
|
|||||||
if !acc.is_empty() {
|
if !acc.is_empty() {
|
||||||
acc.push('\n');
|
acc.push('\n');
|
||||||
}
|
}
|
||||||
match *frag {
|
acc.push_str(&frag.doc);
|
||||||
DocFragment::SugaredDoc(_, _, ref docs)
|
|
||||||
| DocFragment::RawDoc(_, _, ref docs)
|
|
||||||
| DocFragment::Include(_, _, _, ref docs) => acc.push_str(docs),
|
|
||||||
}
|
|
||||||
|
|
||||||
acc
|
acc
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -547,15 +532,15 @@ impl Attributes {
|
|||||||
.filter_map(|attr| {
|
.filter_map(|attr| {
|
||||||
if let Some(value) = attr.doc_str() {
|
if let Some(value) = attr.doc_str() {
|
||||||
let value = beautify_doc_string(value);
|
let value = beautify_doc_string(value);
|
||||||
let mk_fragment: fn(_, _, _) -> _ = if attr.is_doc_comment() {
|
let kind = if attr.is_doc_comment() {
|
||||||
DocFragment::SugaredDoc
|
DocFragmentKind::SugaredDoc
|
||||||
} else {
|
} else {
|
||||||
DocFragment::RawDoc
|
DocFragmentKind::RawDoc
|
||||||
};
|
};
|
||||||
|
|
||||||
let line = doc_line;
|
let line = doc_line;
|
||||||
doc_line += value.lines().count();
|
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() {
|
if sp.is_none() {
|
||||||
sp = Some(attr.span);
|
sp = Some(attr.span);
|
||||||
@@ -575,9 +560,12 @@ impl Attributes {
|
|||||||
{
|
{
|
||||||
let line = doc_line;
|
let line = doc_line;
|
||||||
doc_line += contents.lines().count();
|
doc_line += contents.lines().count();
|
||||||
doc_strings.push(DocFragment::Include(
|
doc_strings.push(DocFragment {
|
||||||
line, attr.span, filename, contents,
|
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
|
/// Finds the `doc` attribute as a NameValue and returns the corresponding
|
||||||
/// value found.
|
/// value found.
|
||||||
pub fn doc_value(&self) -> Option<&str> {
|
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
|
/// 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 };
|
let mut tests = Tests { found_tests: 0 };
|
||||||
|
|
||||||
find_testable_code(
|
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,
|
&mut tests,
|
||||||
ErrorCodes::No,
|
ErrorCodes::No,
|
||||||
false,
|
false,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::clean::{self, DocFragment, Item};
|
use crate::clean::{self, DocFragment, DocFragmentKind, Item};
|
||||||
use crate::core::DocContext;
|
use crate::core::DocContext;
|
||||||
use crate::fold;
|
use crate::fold;
|
||||||
use crate::fold::DocFolder;
|
use crate::fold::DocFolder;
|
||||||
@@ -12,23 +12,6 @@ pub const COLLAPSE_DOCS: Pass = Pass {
|
|||||||
description: "concatenates all document attributes into one document attribute",
|
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 {
|
pub fn collapse_docs(krate: clean::Crate, _: &DocContext<'_>) -> clean::Crate {
|
||||||
let mut krate = Collapser.fold_crate(krate);
|
let mut krate = Collapser.fold_crate(krate);
|
||||||
krate.collapsed = true;
|
krate.collapsed = true;
|
||||||
@@ -50,30 +33,22 @@ fn collapse(doc_strings: &mut Vec<DocFragment>) {
|
|||||||
|
|
||||||
for frag in take(doc_strings) {
|
for frag in take(doc_strings) {
|
||||||
if let Some(mut curr_frag) = last_frag.take() {
|
if let Some(mut curr_frag) = last_frag.take() {
|
||||||
let curr_kind = curr_frag.kind();
|
let curr_kind = &curr_frag.kind;
|
||||||
let new_kind = frag.kind();
|
let new_kind = &frag.kind;
|
||||||
|
|
||||||
if curr_kind == DocFragmentKind::Include || curr_kind != new_kind {
|
if matches!(*curr_kind, DocFragmentKind::Include { .. }) || curr_kind != new_kind {
|
||||||
match curr_frag {
|
if *curr_kind == DocFragmentKind::SugaredDoc
|
||||||
DocFragment::SugaredDoc(_, _, ref mut doc_string)
|
|| *curr_kind == DocFragmentKind::RawDoc
|
||||||
| DocFragment::RawDoc(_, _, ref mut doc_string) => {
|
{
|
||||||
// add a newline for extra padding between segments
|
// add a newline for extra padding between segments
|
||||||
doc_string.push('\n');
|
curr_frag.doc.push('\n');
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
docs.push(curr_frag);
|
docs.push(curr_frag);
|
||||||
last_frag = Some(frag);
|
last_frag = Some(frag);
|
||||||
} else {
|
} else {
|
||||||
match curr_frag {
|
curr_frag.doc.push('\n');
|
||||||
DocFragment::SugaredDoc(_, ref mut span, ref mut doc_string)
|
curr_frag.doc.push_str(&frag.doc);
|
||||||
| DocFragment::RawDoc(_, ref mut span, ref mut doc_string) => {
|
curr_frag.span = curr_frag.span.to(frag.span);
|
||||||
doc_string.push('\n');
|
|
||||||
doc_string.push_str(frag.as_str());
|
|
||||||
*span = span.to(frag.span());
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
last_frag = Some(curr_frag);
|
last_frag = Some(curr_frag);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use std::mem;
|
|||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
use self::Condition::*;
|
use self::Condition::*;
|
||||||
use crate::clean::{self, GetDefId, Item};
|
use crate::clean::{self, DocFragmentKind, GetDefId, Item};
|
||||||
use crate::core::DocContext;
|
use crate::core::DocContext;
|
||||||
use crate::fold::{DocFolder, StripItem};
|
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() {
|
if attrs.doc_strings.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let start = attrs.doc_strings[0].span();
|
let start = attrs.doc_strings[0].span;
|
||||||
if start == DUMMY_SP {
|
if start == DUMMY_SP {
|
||||||
return None;
|
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))
|
Some(start.to(end))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,10 +333,8 @@ crate fn source_span_for_markdown_range(
|
|||||||
md_range: &Range<usize>,
|
md_range: &Range<usize>,
|
||||||
attrs: &clean::Attributes,
|
attrs: &clean::Attributes,
|
||||||
) -> Option<Span> {
|
) -> Option<Span> {
|
||||||
let is_all_sugared_doc = attrs.doc_strings.iter().all(|frag| match frag {
|
let is_all_sugared_doc =
|
||||||
clean::DocFragment::SugaredDoc(..) => true,
|
attrs.doc_strings.iter().all(|frag| frag.kind == DocFragmentKind::SugaredDoc);
|
||||||
_ => false,
|
|
||||||
});
|
|
||||||
|
|
||||||
if !is_all_sugared_doc {
|
if !is_all_sugared_doc {
|
||||||
return None;
|
return None;
|
||||||
|
|||||||
@@ -36,13 +36,7 @@ impl clean::Attributes {
|
|||||||
|
|
||||||
fn unindent_fragments(docs: &mut Vec<DocFragment>) {
|
fn unindent_fragments(docs: &mut Vec<DocFragment>) {
|
||||||
for fragment in docs {
|
for fragment in docs {
|
||||||
match *fragment {
|
fragment.doc = unindent(&fragment.doc);
|
||||||
DocFragment::SugaredDoc(_, _, ref mut doc_string)
|
|
||||||
| DocFragment::RawDoc(_, _, ref mut doc_string)
|
|
||||||
| DocFragment::Include(_, _, _, ref mut doc_string) => {
|
|
||||||
*doc_string = unindent(doc_string)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user