Auto merge of #108209 - petrochenkov:doclean, r=notriddle
rustdoc: Cleanup doc link extraction
This commit is contained in:
commit
53709aedba
3 changed files with 61 additions and 72 deletions
|
@ -1,11 +1,10 @@
|
||||||
use pulldown_cmark::{BrokenLink, Event, Options, Parser, Tag};
|
use pulldown_cmark::{BrokenLink, Event, LinkType, Options, Parser, Tag};
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_ast::util::comments::beautify_doc_string;
|
use rustc_ast::util::comments::beautify_doc_string;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_span::def_id::DefId;
|
use rustc_span::def_id::DefId;
|
||||||
use rustc_span::symbol::{kw, Symbol};
|
use rustc_span::symbol::{kw, Symbol};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::{cmp, mem};
|
use std::{cmp, mem};
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
|
@ -348,22 +347,37 @@ fn preprocess_link(link: &str) -> String {
|
||||||
strip_generics_from_path(link).unwrap_or_else(|_| link.to_string())
|
strip_generics_from_path(link).unwrap_or_else(|_| link.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Keep inline and reference links `[]`,
|
||||||
|
/// but skip autolinks `<>` which we never consider to be intra-doc links.
|
||||||
|
pub fn may_be_doc_link(link_type: LinkType) -> bool {
|
||||||
|
match link_type {
|
||||||
|
LinkType::Inline
|
||||||
|
| LinkType::Reference
|
||||||
|
| LinkType::ReferenceUnknown
|
||||||
|
| LinkType::Collapsed
|
||||||
|
| LinkType::CollapsedUnknown
|
||||||
|
| LinkType::Shortcut
|
||||||
|
| LinkType::ShortcutUnknown => true,
|
||||||
|
LinkType::Autolink | LinkType::Email => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Simplified version of `preprocessed_markdown_links` from rustdoc.
|
/// Simplified version of `preprocessed_markdown_links` from rustdoc.
|
||||||
/// Must return at least the same links as it, but may add some more links on top of that.
|
/// Must return at least the same links as it, but may add some more links on top of that.
|
||||||
pub(crate) fn attrs_to_preprocessed_links(attrs: &[ast::Attribute]) -> Vec<String> {
|
pub(crate) fn attrs_to_preprocessed_links(attrs: &[ast::Attribute]) -> Vec<String> {
|
||||||
let (doc_fragments, _) = attrs_to_doc_fragments(attrs.iter().map(|attr| (attr, None)), true);
|
let (doc_fragments, _) = attrs_to_doc_fragments(attrs.iter().map(|attr| (attr, None)), true);
|
||||||
let doc = prepare_to_doc_link_resolution(&doc_fragments).into_values().next().unwrap();
|
let doc = prepare_to_doc_link_resolution(&doc_fragments).into_values().next().unwrap();
|
||||||
|
|
||||||
let links = RefCell::new(Vec::new());
|
Parser::new_with_broken_link_callback(
|
||||||
let mut callback = |link: BrokenLink<'_>| {
|
&doc,
|
||||||
links.borrow_mut().push(preprocess_link(&link.reference));
|
main_body_opts(),
|
||||||
None
|
Some(&mut |link: BrokenLink<'_>| Some((link.reference, "".into()))),
|
||||||
};
|
)
|
||||||
for event in Parser::new_with_broken_link_callback(&doc, main_body_opts(), Some(&mut callback))
|
.filter_map(|event| match event {
|
||||||
{
|
Event::Start(Tag::Link(link_type, dest, _)) if may_be_doc_link(link_type) => {
|
||||||
if let Event::Start(Tag::Link(_, dest, _)) = event {
|
Some(preprocess_link(&dest))
|
||||||
links.borrow_mut().push(preprocess_link(&dest));
|
|
||||||
}
|
}
|
||||||
}
|
_ => None,
|
||||||
links.into_inner()
|
})
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,12 +29,12 @@ use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::TyCtxt;
|
||||||
pub(crate) use rustc_resolve::rustdoc::main_body_opts;
|
pub(crate) use rustc_resolve::rustdoc::main_body_opts;
|
||||||
|
use rustc_resolve::rustdoc::may_be_doc_link;
|
||||||
use rustc_span::edition::Edition;
|
use rustc_span::edition::Edition;
|
||||||
use rustc_span::{Span, Symbol};
|
use rustc_span::{Span, Symbol};
|
||||||
|
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
@ -1226,14 +1226,12 @@ pub(crate) struct MarkdownLink {
|
||||||
|
|
||||||
pub(crate) fn markdown_links<R>(
|
pub(crate) fn markdown_links<R>(
|
||||||
md: &str,
|
md: &str,
|
||||||
filter_map: impl Fn(MarkdownLink) -> Option<R>,
|
preprocess_link: impl Fn(MarkdownLink) -> Option<R>,
|
||||||
) -> Vec<R> {
|
) -> Vec<R> {
|
||||||
if md.is_empty() {
|
if md.is_empty() {
|
||||||
return vec![];
|
return vec![];
|
||||||
}
|
}
|
||||||
|
|
||||||
let links = RefCell::new(vec![]);
|
|
||||||
|
|
||||||
// FIXME: remove this function once pulldown_cmark can provide spans for link definitions.
|
// FIXME: remove this function once pulldown_cmark can provide spans for link definitions.
|
||||||
let locate = |s: &str, fallback: Range<usize>| unsafe {
|
let locate = |s: &str, fallback: Range<usize>| unsafe {
|
||||||
let s_start = s.as_ptr();
|
let s_start = s.as_ptr();
|
||||||
|
@ -1265,46 +1263,23 @@ pub(crate) fn markdown_links<R>(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut push = |link: BrokenLink<'_>| {
|
Parser::new_with_broken_link_callback(
|
||||||
let span = span_for_link(&link.reference, link.span);
|
md,
|
||||||
filter_map(MarkdownLink {
|
main_body_opts(),
|
||||||
kind: LinkType::ShortcutUnknown,
|
Some(&mut |link: BrokenLink<'_>| Some((link.reference, "".into()))),
|
||||||
link: link.reference.to_string(),
|
)
|
||||||
range: span,
|
.into_offset_iter()
|
||||||
})
|
.filter_map(|(event, span)| match event {
|
||||||
.map(|link| links.borrow_mut().push(link));
|
Event::Start(Tag::Link(link_type, dest, _)) if may_be_doc_link(link_type) => {
|
||||||
None
|
preprocess_link(MarkdownLink {
|
||||||
};
|
kind: link_type,
|
||||||
let p = Parser::new_with_broken_link_callback(md, main_body_opts(), Some(&mut push))
|
range: span_for_link(&dest, span),
|
||||||
.into_offset_iter();
|
link: dest.into_string(),
|
||||||
|
})
|
||||||
// There's no need to thread an IdMap through to here because
|
|
||||||
// the IDs generated aren't going to be emitted anywhere.
|
|
||||||
let mut ids = IdMap::new();
|
|
||||||
let iter = Footnotes::new(HeadingLinks::new(p, None, &mut ids, HeadingOffset::H1));
|
|
||||||
|
|
||||||
for ev in iter {
|
|
||||||
if let Event::Start(Tag::Link(
|
|
||||||
// `<>` links cannot be intra-doc links so we skip them.
|
|
||||||
kind @ (LinkType::Inline
|
|
||||||
| LinkType::Reference
|
|
||||||
| LinkType::ReferenceUnknown
|
|
||||||
| LinkType::Collapsed
|
|
||||||
| LinkType::CollapsedUnknown
|
|
||||||
| LinkType::Shortcut
|
|
||||||
| LinkType::ShortcutUnknown),
|
|
||||||
dest,
|
|
||||||
_,
|
|
||||||
)) = ev.0
|
|
||||||
{
|
|
||||||
debug!("found link: {dest}");
|
|
||||||
let span = span_for_link(&dest, ev.1);
|
|
||||||
filter_map(MarkdownLink { kind, link: dest.into_string(), range: span })
|
|
||||||
.map(|link| links.borrow_mut().push(link));
|
|
||||||
}
|
}
|
||||||
}
|
_ => None,
|
||||||
|
})
|
||||||
links.into_inner()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
|
@ -20,22 +20,6 @@ LL | //! Linking to [foo@banana] and [`bar@banana!()`].
|
||||||
|
|
|
|
||||||
= note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
|
= note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
|
||||||
|
|
||||||
error: unknown disambiguator `foo`
|
|
||||||
--> $DIR/unknown-disambiguator.rs:10:34
|
|
||||||
|
|
|
||||||
LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello].
|
|
||||||
| ^^^
|
|
||||||
|
|
|
||||||
= note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
|
|
||||||
|
|
||||||
error: unknown disambiguator `foo`
|
|
||||||
--> $DIR/unknown-disambiguator.rs:10:48
|
|
||||||
|
|
|
||||||
LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello].
|
|
||||||
| ^^^
|
|
||||||
|
|
|
||||||
= note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
|
|
||||||
|
|
||||||
error: unknown disambiguator ``
|
error: unknown disambiguator ``
|
||||||
--> $DIR/unknown-disambiguator.rs:7:31
|
--> $DIR/unknown-disambiguator.rs:7:31
|
||||||
|
|
|
|
||||||
|
@ -52,5 +36,21 @@ LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()).
|
||||||
|
|
|
|
||||||
= note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
|
= note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
|
||||||
|
|
||||||
|
error: unknown disambiguator `foo`
|
||||||
|
--> $DIR/unknown-disambiguator.rs:10:34
|
||||||
|
|
|
||||||
|
LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello].
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
= note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
|
||||||
|
|
||||||
|
error: unknown disambiguator `foo`
|
||||||
|
--> $DIR/unknown-disambiguator.rs:10:48
|
||||||
|
|
|
||||||
|
LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello].
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
= note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
|
||||||
|
|
||||||
error: aborting due to 6 previous errors
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue