-
Notifications
You must be signed in to change notification settings - Fork 186
/
cyclocomp_linter.R
55 lines (54 loc) · 1.74 KB
/
cyclocomp_linter.R
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
#' Cyclomatic complexity linter
#'
#' Check for overly complicated expressions. See `cyclocomp()` function from `{cyclocomp}`.
#'
#' @param complexity_limit Maximum cyclomatic complexity, default `15`. Expressions more complex
#' than this are linted.
#'
#' @examplesIf requireNamespace("cyclocomp", quietly = TRUE)
#' # will produce lints
#' lint(
#' text = "if (TRUE) 1 else 2",
#' linters = cyclocomp_linter(complexity_limit = 1L)
#' )
#'
#' # okay
#' lint(
#' text = "if (TRUE) 1 else 2",
#' linters = cyclocomp_linter(complexity_limit = 2L)
#' )
#'
#' @evalRd rd_tags("cyclocomp_linter")
#' @seealso [linters] for a complete list of linters available in lintr.
#' @export
cyclocomp_linter <- function(complexity_limit = 15L) {
Linter(linter_level = "expression", function(source_expression) {
# nocov start
if (!requireNamespace("cyclocomp", quietly = TRUE)) {
cli::cli_abort(c(
"Cyclocomp complexity is computed using {.fn cyclocomp::cyclocomp}.",
i = "Please install the needed {.pkg cyclocomp} package."
))
}
# nocov end
complexity <- try_silently(
cyclocomp::cyclocomp(parse(text = source_expression$content))
)
if (inherits(complexity, "try-error") || complexity <= complexity_limit) {
return(list())
}
col1 <- source_expression[["column"]][1L]
Lint(
filename = source_expression[["filename"]],
line_number = source_expression[["line"]][1L],
column_number = source_expression[["column"]][1L],
type = "style",
message = sprintf(
"Reduce the cyclomatic complexity of this function from %d to at most %d.",
complexity, complexity_limit
),
ranges = list(rep(col1, 2L)),
line = source_expression$lines[1L]
)
})
}