| //! Runs several rustdoc lints, consolidating them into a single pass for | |
| //! efficiency and simplicity. | |
| mod bare_urls; | |
| mod check_code_block_syntax; | |
| mod html_tags; | |
| mod redundant_explicit_links; | |
| mod unescaped_backticks; | |
| use super::Pass; | |
| use crate::clean::*; | |
| use crate::core::DocContext; | |
| use crate::visit::DocVisitor; | |
| pub(crate) const RUN_LINTS: Pass = | |
| Pass { name: "run-lints", run: Some(run_lints), description: "runs some of rustdoc's lints" }; | |
| struct Linter<'a, 'tcx> { | |
| cx: &'a mut DocContext<'tcx>, | |
| } | |
| pub(crate) fn run_lints(krate: Crate, cx: &mut DocContext<'_>) -> Crate { | |
| Linter { cx }.visit_crate(&krate); | |
| krate | |
| } | |
| impl DocVisitor<'_> for Linter<'_, '_> { | |
| fn visit_item(&mut self, item: &Item) { | |
| let Some(hir_id) = DocContext::as_local_hir_id(self.cx.tcx, item.item_id) else { | |
| // If non-local, no need to check anything. | |
| return; | |
| }; | |
| let dox = item.doc_value(); | |
| if !dox.is_empty() { | |
| let may_have_link = dox.contains(&[':', '['][..]); | |
| let may_have_block_comment_or_html = dox.contains(['<', '>']); | |
| // ~~~rust | |
| // // This is a real, supported commonmark syntax for block code | |
| // ~~~ | |
| let may_have_code = dox.contains(&['~', '`', '\t'][..]) || dox.contains(" "); | |
| if may_have_link { | |
| bare_urls::visit_item(self.cx, item, hir_id, &dox); | |
| redundant_explicit_links::visit_item(self.cx, item, hir_id); | |
| } | |
| if may_have_code { | |
| check_code_block_syntax::visit_item(self.cx, item, &dox); | |
| unescaped_backticks::visit_item(self.cx, item, hir_id, &dox); | |
| } | |
| if may_have_block_comment_or_html { | |
| html_tags::visit_item(self.cx, item, hir_id, &dox); | |
| } | |
| } | |
| self.visit_item_recur(item) | |
| } | |
| } |