Skip to content

Commit ab17c87

Browse files
authored
Merge 5d95612 into fa914d0
2 parents fa914d0 + 5d95612 commit ab17c87

File tree

11 files changed

+113
-11
lines changed

11 files changed

+113
-11
lines changed

DESCRIPTION

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ Collate:
149149
'redundant_equals_linter.R'
150150
'redundant_ifelse_linter.R'
151151
'regex_subset_linter.R'
152+
'repeat_linter.R'
152153
'routine_registration_linter.R'
153154
'scalar_in_linter.R'
154155
'semicolon_linter.R'

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ export(quotes_linter)
113113
export(redundant_equals_linter)
114114
export(redundant_ifelse_linter)
115115
export(regex_subset_linter)
116+
export(repeat_linter)
116117
export(routine_registration_linter)
117118
export(sarif_output)
118119
export(scalar_in_linter)

NEWS.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
* `seq_linter()` recommends `rev()` in the lint message for lints like `nrow(x):1` (#1542, @MichaelChirico).
3535
* New `xp_call_name()` helper to facilitate writing custom linters (#2023, @MichaelChirico). This helper converts a matched XPath to the R function to which it corresponds. This is useful for including the "offending" function in the lint's message.
3636
* `function_argument_linter()` detects usage of `missing()` for the linted argument (#1546, @MichaelChirico). The simplest fix for `function_argument_linter()` lints is typically to set that argument to `NULL` by default, in which case it's usually preferable to update function logic checking `missing()` to check `is.null()` instead.
37+
* `commas_linter()` gains an option `allow_trailing` (default `FALSE`) to allow trailing commas while indexing. (#2104, @MEO265)
3738

3839
### New linters
3940

@@ -42,7 +43,7 @@
4243
* `length_levels_linter()` for using the specific function `nlevels()` instead of checking `length(levels(x))` (part of #884, @MichaelChirico).
4344
* `scalar_in_linter()` for discouraging `%in%` when the right-hand side is a scalar, e.g. `x %in% 1` (part of #884, @MichaelChirico).
4445
* `if_not_else_linter()` for encouraging `if` statements to be structured as `if (A) x else y` instead of `if (!A) y else x` (part of #884, @MichaelChirico).
45-
* `commas_linter()` gains an option `allow_trailing` (default `FALSE`) to allow trailing commas while indexing. (#2104, @MEO265)
46+
* `repeat_linter()` for encouraging `repeat` for infinite loops instead of `while (TRUE)` (#2106, @MEO265).
4647

4748
## Changes to defaults
4849

R/repeat_linter.R

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#' Repeat linter
2+
#'
3+
#' Check that `while (TRUE)` is not used for infinite loops.
4+
#'
5+
#' @examples
6+
#' # will produce lints
7+
#' lint(
8+
#' text = "while (TRUE) { }",
9+
#' linters = repeat_linter()
10+
#' )
11+
#'
12+
#'
13+
#' # okay
14+
#' lint(
15+
#' text = "repeat { }",
16+
#' linters = repeat_linter()
17+
#' )
18+
#'
19+
#'
20+
#' @evalRd rd_tags("repeat_linter")
21+
#' @seealso [linters] for a complete list of linters available in lintr.
22+
#' @export
23+
repeat_linter <- function() {
24+
xpath <- "//WHILE[following-sibling::expr[1]/NUM_CONST[text() = 'TRUE']]"
25+
26+
Linter(function(source_expression) {
27+
if (!is_lint_level(source_expression, "expression")) {
28+
return(list())
29+
}
30+
xml <- source_expression$xml_parsed_content
31+
lints <- xml_find_all(xml, xpath)
32+
33+
xml_nodes_to_lints(
34+
lints,
35+
source_expression = source_expression,
36+
lint_message = "Use 'repeat' instead of 'while (TRUE)' for infinite loops.",
37+
range_start_xpath = "number(./@col1)",
38+
range_end_xpath = "number(./following-sibling::*[3]/@col2)"
39+
)
40+
})
41+
}

inst/lintr/linters.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ quotes_linter,style consistency readability default configurable
7171
redundant_equals_linter,best_practices readability efficiency common_mistakes
7272
redundant_ifelse_linter,best_practices efficiency consistency configurable
7373
regex_subset_linter,best_practices efficiency
74+
repeat_linter,style readability
7475
routine_registration_linter,best_practices efficiency robustness
7576
scalar_in_linter,readability consistency best_practices efficiency
7677
semicolon_linter,style readability default configurable

man/conjunct_test_linter.Rd

Lines changed: 2 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/linters.Rd

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/readability_linters.Rd

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/repeat_linter.Rd

Lines changed: 33 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/style_linters.Rd

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)