Skip to content

Commit 921a431

Browse files
committed
Check for other unused tidy check directives
1 parent d2185a2 commit 921a431

File tree

1 file changed

+70
-28
lines changed

1 file changed

+70
-28
lines changed

src/tools/tidy/src/style.rs

Lines changed: 70 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
//! * No `TODO` or `XXX` directives.
1010
//! * No unexplained ` ```ignore ` or ` ```rust,ignore ` doc tests.
1111
//!
12-
//! A number of these checks can be opted-out of with various directives like
13-
//! `// ignore-tidy-copyright`.
12+
//! A number of these checks can be opted-out of with various directives of the form:
13+
//! `// ignore-tidy-CHECK-NAME`.
1414
1515
use std::fs::File;
1616
use std::io::prelude::*;
@@ -90,9 +90,34 @@ fn long_line_is_ok(line: &str) -> bool {
9090
false
9191
}
9292

93-
fn contains_ignore_directive(contents: &String, check: &str) -> bool {
94-
contents.contains(&format!("// ignore-tidy-{}", check)) ||
95-
contents.contains(&format!("# ignore-tidy-{}", check))
93+
enum Directive {
94+
/// By default, tidy always warns against style issues.
95+
Deny,
96+
97+
/// `Ignore(false)` means that an `ignore-tidy-*` directive
98+
/// has been provided, but is unnecessary. `Ignore(true)`
99+
/// means that it is necessary (i.e. a warning would be
100+
/// produced if `ignore-tidy-*` was not present).
101+
Ignore(bool),
102+
}
103+
104+
fn contains_ignore_directive(contents: &String, check: &str) -> Directive {
105+
if contents.contains(&format!("// ignore-tidy-{}", check)) ||
106+
contents.contains(&format!("# ignore-tidy-{}", check)) {
107+
Directive::Ignore(false)
108+
} else {
109+
Directive::Deny
110+
}
111+
}
112+
113+
macro_rules! suppressible_tidy_err {
114+
($err:ident, $skip:ident, $msg:expr) => {
115+
if let Directive::Deny = $skip {
116+
$err($msg);
117+
} else {
118+
$skip = Directive::Ignore(true);
119+
}
120+
};
96121
}
97122

98123
pub fn check(path: &Path, bad: &mut bool) {
@@ -112,32 +137,32 @@ pub fn check(path: &Path, bad: &mut bool) {
112137
tidy_error!(bad, "{}: empty file", file.display());
113138
}
114139

115-
let skip_cr = contains_ignore_directive(&contents, "cr");
116-
let skip_tab = contains_ignore_directive(&contents, "tab");
117-
let skip_length = contains_ignore_directive(&contents, "linelength");
118-
let skip_end_whitespace = contains_ignore_directive(&contents, "end-whitespace");
119-
let skip_copyright = contains_ignore_directive(&contents, "copyright");
140+
let mut skip_cr = contains_ignore_directive(&contents, "cr");
141+
let mut skip_tab = contains_ignore_directive(&contents, "tab");
142+
let mut skip_length = contains_ignore_directive(&contents, "linelength");
143+
let mut skip_end_whitespace = contains_ignore_directive(&contents, "end-whitespace");
144+
let mut skip_copyright = contains_ignore_directive(&contents, "copyright");
120145
let mut leading_new_lines = false;
121146
let mut trailing_new_lines = 0;
122-
let mut contained_long_line = false;
123147
for (i, line) in contents.split('\n').enumerate() {
124148
let mut err = |msg: &str| {
125149
tidy_error!(bad, "{}:{}: {}", file.display(), i + 1, msg);
126150
};
127151
if line.chars().count() > COLS && !long_line_is_ok(line) {
128-
contained_long_line = true;
129-
if !skip_length {
130-
err(&format!("line longer than {} chars", COLS));
131-
}
152+
suppressible_tidy_err!(
153+
err,
154+
skip_length,
155+
&format!("line longer than {} chars", COLS)
156+
);
132157
}
133-
if !skip_tab && line.contains('\t') {
134-
err("tab character");
158+
if line.contains('\t') {
159+
suppressible_tidy_err!(err, skip_tab, "tab character");
135160
}
136-
if !skip_end_whitespace && (line.ends_with(' ') || line.ends_with('\t')) {
137-
err("trailing whitespace");
161+
if line.ends_with(' ') || line.ends_with('\t') {
162+
suppressible_tidy_err!(err, skip_end_whitespace, "trailing whitespace");
138163
}
139-
if !skip_cr && line.contains('\r') {
140-
err("CR character");
164+
if line.contains('\r') {
165+
suppressible_tidy_err!(err, skip_cr, "CR character");
141166
}
142167
if filename != "style.rs" {
143168
if line.contains("TODO") {
@@ -147,12 +172,16 @@ pub fn check(path: &Path, bad: &mut bool) {
147172
err("XXX is deprecated; use FIXME")
148173
}
149174
}
150-
if !skip_copyright && (line.starts_with("// Copyright") ||
151-
line.starts_with("# Copyright") ||
152-
line.starts_with("Copyright"))
153-
&& (line.contains("Rust Developers") ||
154-
line.contains("Rust Project Developers")) {
155-
err("copyright notices attributed to the Rust Project Developers are deprecated");
175+
if (line.starts_with("// Copyright") ||
176+
line.starts_with("# Copyright") ||
177+
line.starts_with("Copyright"))
178+
&& (line.contains("Rust Developers") ||
179+
line.contains("Rust Project Developers")) {
180+
suppressible_tidy_err!(
181+
err,
182+
skip_copyright,
183+
"copyright notices attributed to the Rust Project Developers are deprecated"
184+
);
156185
}
157186
if line.ends_with("```ignore") || line.ends_with("```rust,ignore") {
158187
err(UNEXPLAINED_IGNORE_DOCTEST_INFO);
@@ -177,8 +206,21 @@ pub fn check(path: &Path, bad: &mut bool) {
177206
1 | 2 => {}
178207
n => tidy_error!(bad, "{}: too many trailing newlines ({})", file.display(), n),
179208
};
180-
if !contained_long_line && skip_length {
209+
210+
if let Directive::Ignore(false) = skip_cr {
211+
tidy_error!(bad, "{}: ignoring CR characters unnecessarily", file.display());
212+
}
213+
if let Directive::Ignore(false) = skip_tab {
214+
tidy_error!(bad, "{}: ignoring tab characters unnecessarily", file.display());
215+
}
216+
if let Directive::Ignore(false) = skip_length {
181217
tidy_error!(bad, "{}: ignoring line length unnecessarily", file.display());
182218
}
219+
if let Directive::Ignore(false) = skip_end_whitespace {
220+
tidy_error!(bad, "{}: ignoring trailing whitespace unnecessarily", file.display());
221+
}
222+
if let Directive::Ignore(false) = skip_copyright {
223+
tidy_error!(bad, "{}: ignoring copyright unnecessarily", file.display());
224+
}
183225
})
184226
}

0 commit comments

Comments
 (0)