-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
Copy pathtoo_many_lines.rs
81 lines (75 loc) · 2.58 KB
/
too_many_lines.rs
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
use clippy_utils::diagnostics::span_lint;
use clippy_utils::source::SpanRangeExt;
use rustc_hir as hir;
use rustc_hir::intravisit::FnKind;
use rustc_lint::{LateContext, LintContext};
use rustc_span::Span;
use super::TOO_MANY_LINES;
pub(super) fn check_fn(
cx: &LateContext<'_>,
kind: FnKind<'_>,
span: Span,
body: &hir::Body<'_>,
too_many_lines_threshold: u64,
) {
// Closures must be contained in a parent body, which will be checked for `too_many_lines`.
// Don't check closures for `too_many_lines` to avoid duplicated lints.
if matches!(kind, FnKind::Closure) || span.in_external_macro(cx.sess().source_map()) {
return;
}
let mut line_count: u64 = 0;
let too_many = body.value.span.check_source_text(cx, |src| {
let mut in_comment = false;
let mut code_in_line;
let function_lines = if matches!(body.value.kind, hir::ExprKind::Block(..))
&& src.as_bytes().first().copied() == Some(b'{')
&& src.as_bytes().last().copied() == Some(b'}')
{
// Removing the braces from the enclosing block
&src[1..src.len() - 1]
} else {
src
}
.trim() // Remove leading and trailing blank lines
.lines();
for mut line in function_lines {
code_in_line = false;
loop {
line = line.trim_start();
if line.is_empty() {
break;
}
if in_comment {
if let Some(i) = line.find("*/") {
line = &line[i + 2..];
in_comment = false;
continue;
}
} else {
let multi_idx = line.find("/*").unwrap_or(line.len());
let single_idx = line.find("//").unwrap_or(line.len());
code_in_line |= multi_idx > 0 && single_idx > 0;
// Implies multi_idx is below line.len()
if multi_idx < single_idx {
line = &line[multi_idx + 2..];
in_comment = true;
continue;
}
}
break;
}
if code_in_line {
line_count += 1;
}
}
line_count > too_many_lines_threshold
});
if too_many {
span_lint(
cx,
TOO_MANY_LINES,
span,
format!("this function has too many lines ({line_count}/{too_many_lines_threshold})"),
);
}
}