Skip to content

Commit c1c935d

Browse files
committed
Merge pull request #836 from Manishearth/doc
Fix false positive with `DOC_MARKDOWN` and `32MiB`
2 parents 69913e6 + ee907b7 commit c1c935d

File tree

4 files changed

+39
-8
lines changed

4 files changed

+39
-8
lines changed

src/doc.rs

+23-7
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,16 @@ declare_lint! {
2424
"checks for the presence of `_`, `::` or camel-case outside ticks in documentation"
2525
}
2626

27-
#[derive(Copy,Clone)]
28-
pub struct Doc;
27+
#[derive(Clone)]
28+
pub struct Doc {
29+
valid_idents: Vec<String>,
30+
}
31+
32+
impl Doc {
33+
pub fn new(valid_idents: Vec<String>) -> Self {
34+
Doc { valid_idents: valid_idents }
35+
}
36+
}
2937

3038
impl LintPass for Doc {
3139
fn get_lints(&self) -> LintArray {
@@ -35,11 +43,11 @@ impl LintPass for Doc {
3543

3644
impl EarlyLintPass for Doc {
3745
fn check_crate(&mut self, cx: &EarlyContext, krate: &ast::Crate) {
38-
check_attrs(cx, &krate.attrs, krate.span);
46+
check_attrs(cx, &self.valid_idents, &krate.attrs, krate.span);
3947
}
4048

4149
fn check_item(&mut self, cx: &EarlyContext, item: &ast::Item) {
42-
check_attrs(cx, &item.attrs, item.span);
50+
check_attrs(cx, &self.valid_idents, &item.attrs, item.span);
4351
}
4452
}
4553

@@ -73,7 +81,7 @@ fn collect_doc(attrs: &[ast::Attribute]) -> (Cow<str>, Option<Span>) {
7381
}
7482
}
7583

76-
pub fn check_attrs<'a>(cx: &EarlyContext, attrs: &'a [ast::Attribute], default_span: Span) {
84+
pub fn check_attrs<'a>(cx: &EarlyContext, valid_idents: &[String], attrs: &'a [ast::Attribute], default_span: Span) {
7785
let (doc, span) = collect_doc(attrs);
7886
let span = span.unwrap_or(default_span);
7987

@@ -100,15 +108,19 @@ pub fn check_attrs<'a>(cx: &EarlyContext, attrs: &'a [ast::Attribute], default_s
100108
}
101109

102110
if !in_ticks {
103-
check_word(cx, word, span);
111+
check_word(cx, valid_idents, word, span);
104112
}
105113
}
106114
}
107115

108-
fn check_word(cx: &EarlyContext, word: &str, span: Span) {
116+
fn check_word(cx: &EarlyContext, valid_idents: &[String], word: &str, span: Span) {
109117
/// Checks if a string a camel-case, ie. contains at least two uppercase letter (`Clippy` is
110118
/// ok) and one lower-case letter (`NASA` is ok). Plural are also excluded (`IDs` is ok).
111119
fn is_camel_case(s: &str) -> bool {
120+
if s.starts_with(|c: char| c.is_digit(10)) {
121+
return false;
122+
}
123+
112124
let s = if s.ends_with('s') {
113125
&s[..s.len()-1]
114126
} else {
@@ -134,6 +146,10 @@ fn check_word(cx: &EarlyContext, word: &str, span: Span) {
134146
// Or even as in `_foo bar_` which is emphasized.
135147
let word = word.trim_matches(|c: char| !c.is_alphanumeric());
136148

149+
if valid_idents.iter().any(|i| i == word) {
150+
return;
151+
}
152+
137153
if has_underscore(word) || word.contains("::") || is_camel_case(word) {
138154
span_lint(cx, DOC_MARKDOWN, span, &format!("you should put `{}` between ticks in the documentation", word));
139155
}

src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
233233
reg.register_late_lint_pass(box new_without_default::NewWithoutDefault);
234234
reg.register_late_lint_pass(box blacklisted_name::BlackListedName::new(conf.blacklisted_names));
235235
reg.register_late_lint_pass(box functions::Functions::new(conf.too_many_arguments_threshold));
236-
reg.register_early_lint_pass(box doc::Doc);
236+
reg.register_early_lint_pass(box doc::Doc::new(conf.doc_valid_idents));
237237

238238
reg.register_lint_group("clippy_pedantic", vec![
239239
array_indexing::INDEXING_SLICING,

src/utils/conf.rs

+2
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ define_Conf! {
149149
("blacklisted-names", blacklisted_names, ["foo", "bar", "baz"] => Vec<String>),
150150
/// Lint: CYCLOMATIC_COMPLEXITY. The maximum cyclomatic complexity a function can have
151151
("cyclomatic-complexity-threshold", cyclomatic_complexity_threshold, 25 => u64),
152+
/// Lint: DOC_MARKDOWN. The list of words this lint should not consider as identifiers needing ticks
153+
("doc-valid-idents", doc_valid_idents, ["MiB", "GiB", "TiB", "PiB", "EiB"] => Vec<String>),
152154
/// Lint: TOO_MANY_ARGUMENTS. The maximum number of argument a function or method can have
153155
("too-many-arguments-threshold", too_many_arguments_threshold, 7 => u64),
154156
/// Lint: TYPE_COMPLEXITY. The maximum complexity a type can have

tests/compile-fail/doc.rs

+13
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,18 @@ fn multiline_ticks() {
2929
fn test_emphasis() {
3030
}
3131

32+
/// This tests units. See also #835.
33+
/// kiB MiB GiB TiB PiB EiB
34+
/// kib Mib Gib Tib Pib Eib
35+
/// kB MB GB TB PB EB
36+
/// kb Mb Gb Tb Pb Eb
37+
/// 32kiB 32MiB 32GiB 32TiB 32PiB 32EiB
38+
/// 32kib 32Mib 32Gib 32Tib 32Pib 32Eib
39+
/// 32kB 32MB 32GB 32TB 32PB 32EB
40+
/// 32kb 32Mb 32Gb 32Tb 32Pb 32Eb
41+
fn test_units() {
42+
}
43+
3244
/// This test has [a link with underscores][chunked-example] inside it. See #823.
3345
/// See also [the issue tracker](https://github.com/Manishearth/rust-clippy/search?q=doc_markdown&type=Issues).
3446
///
@@ -40,4 +52,5 @@ fn main() {
4052
foo_bar();
4153
multiline_ticks();
4254
test_emphasis();
55+
test_units();
4356
}

0 commit comments

Comments
 (0)