Skip to content

Commit 856f1dd

Browse files
New numeric_leading_zero_linter (#992)
Co-authored-by: AshesITR <alexander.rosenstock@web.de>
1 parent eefe67b commit 856f1dd

11 files changed

+86
-1
lines changed

DESCRIPTION

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ Collate:
9393
'namespace.R'
9494
'namespace_linter.R'
9595
'no_tab_linter.R'
96+
'numeric_leading_zero_linter.R'
9697
'object_name_linters.R'
9798
'object_usage_linter.R'
9899
'open_curly_linter.R'

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export(missing_package_linter)
5858
export(namespace_linter)
5959
export(no_tab_linter)
6060
export(nonportable_path_linter)
61+
export(numeric_leading_zero_linter)
6162
export(object_length_linter)
6263
export(object_name_linter)
6364
export(object_usage_linter)

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ function calls. (#850, #851, @renkun-ken)
101101
* `vector_logic_linter()` Require use of scalar logical operators (`&&` and `||`) inside `if()` conditions and similar
102102
* `any_is_na_linter()` Require usage of `anyNA(x)` over `any(is.na(x))`
103103
* `outer_negation_linter()` Require usage of `!any(x)` over `all(!x)` and `!all(x)` over `any(!x)`
104+
* `numeric_leading_zero_linter()` Require a leading `0` in fractional numeric constants, e.g. `0.1` instead of `.1`
104105
* `assignment_linter()` now lints right assignment (`->` and `->>`) and gains two arguments. `allow_cascading_assign` (`TRUE` by default) toggles whether to lint `<<-` and `->>`; `allow_right_assign` toggles whether to lint `->` and `->>` (#915, @michaelchirico)
105106
* `infix_spaces_linter()` gains argument `exclude_operators` to disable lints on selected infix operators. By default, all "low-precedence" operators throw lints; see `?infix_spaces_linter` for an enumeration of these. (#914 @michaelchirico)
106107
* `infix_spaces_linter()` now throws a lint on `a~b` and `function(a=1) {}` (#930, @michaelchirico)

R/numeric_leading_zero_linter.R

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#' Require usage of a leading zero in all fractional numerics
2+
#'
3+
#' While .1 and 0.1 mean the same thing, the latter is easier to read due
4+
#' to the small size of the '.' glyph.
5+
#'
6+
#' @evalRd rd_tags("numeric_leading_zero_linter")
7+
#' @seealso [linters] for a complete list of linters available in lintr.
8+
#' @export
9+
numeric_leading_zero_linter <- function() {
10+
Linter(function(source_file) {
11+
if (length(source_file$parsed_content) == 0L) {
12+
return(list())
13+
}
14+
15+
xml <- source_file$xml_parsed_content
16+
17+
# NB:
18+
# 1. negative constants are split to two components:
19+
# OP-MINUS, NUM_CONST
20+
# 2. complex constants are split to three components:
21+
# NUM_CONST, OP-PLUS/OP-MINUS, NUM_CONST
22+
xpath <- "//NUM_CONST[starts-with(text(), '.')]"
23+
24+
bad_expr <- xml2::xml_find_all(xml, xpath)
25+
26+
return(lapply(
27+
bad_expr,
28+
xml_nodes_to_lint,
29+
source_file = source_file,
30+
lint_message = "Include the leading zero for fractional numeric constants.",
31+
type = "warning"
32+
))
33+
})
34+
}

inst/lintr/linters.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ missing_package_linter,robustness common_mistakes
3131
namespace_linter,correctness robustness configurable
3232
no_tab_linter,style consistency default
3333
nonportable_path_linter,robustness best_practices configurable
34+
numeric_leading_zero_linter,style consistency readability
3435
object_length_linter,style readability default configurable
3536
object_name_linter,style consistency default configurable
3637
object_usage_linter,style readability correctness default

man/consistency_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/linters.Rd

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

man/numeric_leading_zero_linter.Rd

Lines changed: 18 additions & 0 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/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.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
test_that("numeric_leading_zero_linter skips allowed usages", {
2+
expect_lint("a <- 0.1", NULL, numeric_leading_zero_linter())
3+
expect_lint("b <- -0.2", NULL, numeric_leading_zero_linter())
4+
expect_lint("c <- 3.0", NULL, numeric_leading_zero_linter())
5+
expect_lint("d <- 4L", NULL, numeric_leading_zero_linter())
6+
expect_lint("e <- TRUE", NULL, numeric_leading_zero_linter())
7+
expect_lint("f <- 0.5e6", NULL, numeric_leading_zero_linter())
8+
expect_lint("g <- 0x78", NULL, numeric_leading_zero_linter())
9+
expect_lint("h <- 0.9 + 0.1i", NULL, numeric_leading_zero_linter())
10+
expect_lint("h <- 0.9+0.1i", NULL, numeric_leading_zero_linter())
11+
expect_lint("h <- 0.9 - 0.1i", NULL, numeric_leading_zero_linter())
12+
expect_lint("i <- 2L + 3.4i", NULL, numeric_leading_zero_linter())
13+
})
14+
15+
test_that("numeric_leading_zero_linter blocks simple disallowed usages", {
16+
linter <- numeric_leading_zero_linter()
17+
lint_message <- rex::rex("Include the leading zero for fractional numeric constants.")
18+
19+
expect_lint("a <- .1", lint_message, linter)
20+
expect_lint("b <- -.2", lint_message, linter)
21+
expect_lint("c <- .3 + 4.5i", lint_message, linter)
22+
expect_lint("d <- 6.7 + .8i", lint_message, linter)
23+
expect_lint("d <- 6.7+.8i", lint_message, linter)
24+
expect_lint("e <- .9e10", lint_message, linter)
25+
})

0 commit comments

Comments
 (0)