]> git.proxmox.com Git - rustc.git/blame - vendor/sysinfo/tests/code_checkers/docs.rs
New upstream version 1.73.0+dfsg1
[rustc.git] / vendor / sysinfo / tests / code_checkers / docs.rs
CommitLineData
923072b8
FG
1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use super::utils::{show_error, TestResult};
4use std::ffi::OsStr;
5use std::path::Path;
6
7fn to_correct_name(s: &str) -> String {
8 let mut out = String::with_capacity(s.len());
9
10 for c in s.chars() {
11 if c.is_uppercase() {
12 if !out.is_empty() {
13 out.push('_');
14 }
15 out.push_str(c.to_lowercase().to_string().as_str());
16 } else {
17 out.push(c);
18 }
19 }
20 out
21}
22
23fn check_md_doc_path(p: &Path, md_line: &str, ty_line: &str) -> bool {
487cf647 24 let parts = md_line.split('/').collect::<Vec<_>>();
923072b8 25 if let Some(md_name) = parts.last().and_then(|n| n.split(".md").next()) {
487cf647 26 if let Some(name) = ty_line.split_whitespace().filter(|s| !s.is_empty()).nth(2) {
923072b8
FG
27 if let Some(name) = name
28 .split('<')
29 .next()
30 .and_then(|n| n.split('{').next())
31 .and_then(|n| n.split('(').next())
32 .and_then(|n| n.split(';').next())
33 {
34 let correct = to_correct_name(name);
35 if correct.as_str() == md_name {
36 return true;
37 }
38 show_error(
39 p,
40 &format!(
add651ee 41 "Invalid markdown file name `{md_name}`, should have been `{correct}`",
923072b8
FG
42 ),
43 );
44 return false;
45 }
46 }
487cf647 47 show_error(p, &format!("Cannot extract type name from `{ty_line}`"));
923072b8 48 } else {
487cf647 49 show_error(p, &format!("Cannot extract md name from `{md_line}`"));
923072b8 50 }
487cf647 51 false
923072b8
FG
52}
53
54fn check_doc_comments_before(p: &Path, lines: &[&str], start: usize) -> bool {
55 let mut found_docs = false;
56
57 for pos in (0..start).rev() {
58 let trimmed = lines[pos].trim();
59 if trimmed.starts_with("///") {
60 if !lines[start].trim().starts_with("pub enum ThreadStatus {") {
61 show_error(
62 p,
63 &format!(
64 "Types should use common documentation by using `#[doc = include_str!(` \
65 and by putting the markdown file in the `md_doc` folder instead of `{}`",
66 &lines[pos],
67 ),
68 );
69 return false;
70 }
71 return true;
72 } else if trimmed.starts_with("#[doc = include_str!(") {
73 found_docs = true;
74 if !check_md_doc_path(p, trimmed, lines[start]) {
75 return false;
76 }
77 } else if !trimmed.starts_with("#[") && !trimmed.starts_with("//") {
78 break;
79 }
80 }
81 if !found_docs {
82 show_error(
83 p,
84 &format!(
85 "Missing documentation for public item: `{}` (if it's not supposed to be a public \
86 item, use `pub(crate)` instead)",
87 lines[start],
88 ),
89 );
90 return false;
91 }
92 true
93}
94
95pub fn check_docs(content: &str, p: &Path) -> TestResult {
96 let mut res = TestResult {
97 nb_tests: 0,
98 nb_errors: 0,
99 };
100
101 // No need to check if we are in the `src` folder or if we are in a `ffi.rs` file.
102 if p.parent().unwrap().file_name().unwrap() == OsStr::new("src")
103 || p.file_name().unwrap() == OsStr::new("ffi.rs")
104 {
105 return res;
106 }
107 let lines = content.lines().collect::<Vec<_>>();
108
109 for pos in 1..lines.len() {
110 let line = lines[pos];
111 let trimmed = line.trim();
112 if trimmed.starts_with("//!") {
113 show_error(p, "There shouln't be inner doc comments (`//!`)");
114 res.nb_tests += 1;
115 res.nb_errors += 1;
116 continue;
117 } else if !line.starts_with("pub fn ")
118 && !trimmed.starts_with("pub struct ")
119 && !trimmed.starts_with("pub enum ")
120 {
121 continue;
122 }
123 res.nb_tests += 1;
124 if !check_doc_comments_before(p, &lines, pos) {
125 res.nb_errors += 1;
126 }
127 }
128 res
129}