1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use super::*;
pub struct MissingDocsRule;
impl Rule for MissingDocsRule {
fn name(&self) -> &'static str {
"missing-docs"
}
fn check(&self, ctx: &mut RuleContext) {
// Collect items to check first to avoid borrowing issues
let mut issues_to_report = Vec::new();
for item in &ctx.syntax_tree.items {
match item {
syn::Item::Fn(f) if is_pub(&f.vis) => {
if !has_doc_comment(&f.attrs) {
let (line, col) = ctx.line_col(f.sig.ident.span());
issues_to_report.push(Issue {
rule: self.name().to_string(),
severity: Severity::Warning,
message: format!("Missing documentation for public function '{}'", f.sig.ident),
location: Location {
line,
column: col,
end_line: None,
end_column: None,
},
fix: None,
});
}
}
syn::Item::Struct(s) if is_pub(&s.vis) => {
if !has_doc_comment(&s.attrs) {
let (line, col) = ctx.line_col(s.ident.span());
issues_to_report.push(Issue {
rule: self.name().to_string(),
severity: Severity::Warning,
message: format!("Missing documentation for public struct '{}'", s.ident),
location: Location {
line,
column: col,
end_line: None,
end_column: None,
},
fix: None,
});
}
}
syn::Item::Enum(e) if is_pub(&e.vis) => {
if !has_doc_comment(&e.attrs) {
let (line, col) = ctx.line_col(e.ident.span());
issues_to_report.push(Issue {
rule: self.name().to_string(),
severity: Severity::Warning,
message: format!("Missing documentation for public enum '{}'", e.ident),
location: Location {
line,
column: col,
end_line: None,
end_column: None,
},
fix: None,
});
}
}
syn::Item::Trait(t) if is_pub(&t.vis) => {
if !has_doc_comment(&t.attrs) {
let (line, col) = ctx.line_col(t.ident.span());
issues_to_report.push(Issue {
rule: self.name().to_string(),
severity: Severity::Warning,
message: format!("Missing documentation for public trait '{}'", t.ident),
location: Location {
line,
column: col,
end_line: None,
end_column: None,
},
fix: None,
});
}
}
_ => {}
}
}
// Report all issues
for issue in issues_to_report {
ctx.report(issue);
}
}
}
fn is_pub(vis: &syn::Visibility) -> bool {
matches!(vis, syn::Visibility::Public(_))
}
fn has_doc_comment(attrs: &[syn::Attribute]) -> bool {
attrs.iter().any(|attr| attr.path().is_ident("doc"))
}