Introduce Divider
This distinguishes between documentation on the original from docs on the re-export
This commit is contained in:
parent
fa1b15f627
commit
8fbfdc548a
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user