Introduce Divider

This distinguishes between documentation on the original from docs on
the re-export
This commit is contained in:
Joshua Nelson 2020-10-04 11:15:45 -04:00
parent fa1b15f627
commit 8fbfdc548a

View File

@ -391,6 +391,24 @@ pub enum DocFragmentKind {
/// A doc fragment created from a `#[doc(include="filename")]` attribute. Contains both the
/// given filename and the file contents.
Include { filename: String },
/// A doc fragment used to distinguish between documentation in different modules.
///
/// In particular, this prevents `collapse_docs` from turning all documentation comments
/// into a single giant attributes even when the item is re-exported with documentation on the re-export.
Divider,
}
impl DocFragment {
/// Creates a dummy doc-fragment which divides earlier and later fragments.
fn divider() -> Self {
DocFragment {
line: 0,
span: DUMMY_SP,
parent_module: None,
doc: String::new(),
kind: DocFragmentKind::Divider,
}
}
}
impl<'a> FromIterator<&'a DocFragment> for String {
@ -531,68 +549,72 @@ impl Attributes {
attrs: &[ast::Attribute],
additional_attrs: Option<(&[ast::Attribute], DefId)>,
) -> Attributes {
let mut doc_strings = vec![];
let doc_strings = RefCell::new(vec![]);
let mut sp = None;
let mut cfg = Cfg::True;
let mut doc_line = 0;
let clean_attr = |(attr, parent_module): (&ast::Attribute, _)| {
if let Some(value) = attr.doc_str() {
trace!("got doc_str={:?}", value);
let value = beautify_doc_string(value);
let kind = if attr.is_doc_comment() {
DocFragmentKind::SugaredDoc
} else {
DocFragmentKind::RawDoc
};
let line = doc_line;
doc_line += value.lines().count();
doc_strings.borrow_mut().push(DocFragment {
line,
span: attr.span,
doc: value,
kind,
parent_module,
});
if sp.is_none() {
sp = Some(attr.span);
}
None
} else {
if attr.has_name(sym::doc) {
if let Some(mi) = attr.meta() {
if let Some(cfg_mi) = Attributes::extract_cfg(&mi) {
// Extracted #[doc(cfg(...))]
match Cfg::parse(cfg_mi) {
Ok(new_cfg) => cfg &= new_cfg,
Err(e) => diagnostic.span_err(e.span, e.msg),
}
} else if let Some((filename, contents)) = Attributes::extract_include(&mi)
{
let line = doc_line;
doc_line += contents.lines().count();
doc_strings.borrow_mut().push(DocFragment {
line,
span: attr.span,
doc: contents,
kind: DocFragmentKind::Include { filename },
parent_module: parent_module,
});
}
}
}
Some(attr.clone())
}
};
// Additional documentation should be shown before the original documentation
let other_attrs = additional_attrs
.into_iter()
.map(|(attrs, id)| attrs.iter().map(move |attr| (attr, Some(id))))
.map(|(attrs, id)| {
doc_strings.borrow_mut().push(DocFragment::divider());
attrs.iter().map(move |attr| (attr, Some(id)))
})
.flatten()
.chain(attrs.iter().map(|attr| (attr, None)))
.filter_map(|(attr, parent_module)| {
if let Some(value) = attr.doc_str() {
trace!("got doc_str={:?}", value);
let value = beautify_doc_string(value);
let kind = if attr.is_doc_comment() {
DocFragmentKind::SugaredDoc
} else {
DocFragmentKind::RawDoc
};
let line = doc_line;
doc_line += value.lines().count();
doc_strings.push(DocFragment {
line,
span: attr.span,
doc: value,
kind,
parent_module,
});
if sp.is_none() {
sp = Some(attr.span);
}
None
} else {
if attr.has_name(sym::doc) {
if let Some(mi) = attr.meta() {
if let Some(cfg_mi) = Attributes::extract_cfg(&mi) {
// Extracted #[doc(cfg(...))]
match Cfg::parse(cfg_mi) {
Ok(new_cfg) => cfg &= new_cfg,
Err(e) => diagnostic.span_err(e.span, e.msg),
}
} else if let Some((filename, contents)) =
Attributes::extract_include(&mi)
{
let line = doc_line;
doc_line += contents.lines().count();
doc_strings.push(DocFragment {
line,
span: attr.span,
doc: contents,
kind: DocFragmentKind::Include { filename },
parent_module: parent_module,
});
}
}
}
Some(attr.clone())
}
})
.filter_map(clean_attr)
.collect();
// treat #[target_feature(enable = "feat")] attributes as if they were
@ -618,7 +640,7 @@ impl Attributes {
.map_or(true, |a| a.style == AttrStyle::Inner);
Attributes {
doc_strings,
doc_strings: doc_strings.into_inner(),
other_attrs,
cfg: if cfg == Cfg::True { None } else { Some(Arc::new(cfg)) },
span: sp,