1mod bare_urls;
4mod check_code_block_syntax;
5mod footnotes;
6mod html_tags;
7mod invalid_markdown_table;
8mod redundant_explicit_links;
9mod unescaped_backticks;
10
11use crate::clean::*;
12use crate::core::DocContext;
13use crate::visit::DocVisitor;
14
15struct Linter<'a, 'tcx> {
16 cx: &'a mut DocContext<'tcx>,
17}
18
19pub(super) fn lint(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
20 Linter { cx }.visit_crate(&krate);
21 krate
22}
23
24impl DocVisitor<'_> for Linter<'_, '_> {
25 fn visit_item(&mut self, item: &Item) {
26 let Some(hir_id) = DocContext::as_local_hir_id(self.cx.tcx, item.item_id) else {
27 return;
29 };
30 let dox = item.doc_value();
31 if !dox.is_empty() {
32 let may_have_link = dox.contains(&[':', '['][..]);
33 let may_have_block_comment_or_html = dox.contains(['<', '>']);
34 let may_have_table = dox.contains(&['|'][..]);
35 let may_have_code = dox.contains(&['~', '`', '\t'][..]) || dox.contains(" ");
39 if may_have_link {
40 bare_urls::visit_item(self.cx, item, hir_id, &dox);
41 redundant_explicit_links::visit_item(self.cx, item, hir_id);
42 footnotes::visit_item(self.cx, item, hir_id, &dox);
43 }
44 if may_have_code {
45 check_code_block_syntax::visit_item(self.cx, item, &dox);
46 unescaped_backticks::visit_item(self.cx, item, hir_id, &dox);
47 }
48 if may_have_block_comment_or_html {
49 html_tags::visit_item(self.cx, item, hir_id, &dox);
50 }
51 if may_have_table {
52 invalid_markdown_table::visit_item(self.cx, item, hir_id, &dox);
53 }
54 }
55
56 self.visit_item_recur(item)
57 }
58}