Skip to content

Commit 802e654

Browse files
Merge branch 'main' into on-cap
2 parents 4affd9c + 8f096fe commit 802e654

16 files changed

+301
-24
lines changed

R/comparison_negation_linter.R

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,34 @@
33
#' `!(x == y)` is more readably expressed as `x != y`. The same is true of
44
#' other negations of simple comparisons like `!(x > y)` and `!(x <= y)`.
55
#'
6+
#' @examples
7+
#' # will produce lints
8+
#' lint(
9+
#' text = "!x == 2",
10+
#' linters = comparison_negation_linter()
11+
#' )
12+
#'
13+
#' lint(
14+
#' text = "!(x > 2)",
15+
#' linters = comparison_negation_linter()
16+
#' )
17+
#'
18+
#' # okay
19+
#' lint(
20+
#' text = "!(x == 2 & y > 2)",
21+
#' linters = comparison_negation_linter()
22+
#' )
23+
#'
24+
#' lint(
25+
#' text = "!(x & y)",
26+
#' linters = comparison_negation_linter()
27+
#' )
28+
#'
29+
#' lint(
30+
#' text = "x != 2",
31+
#' linters = comparison_negation_linter()
32+
#' )
33+
#'
634
#' @evalRd rd_tags("comparison_negation_linter")
735
#' @seealso [linters] for a complete list of linters available in lintr.
836
#' @export

R/get_source_expressions.R

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,7 @@ get_source_expressions <- function(filename, lines = NULL) {
6868
}
6969

7070
# Only regard explicit attribute terminal_newline=FALSE as FALSE and all other cases (e.g. NULL or TRUE) as TRUE.
71-
# We don't use isFALSE since it is introduced in R 3.5.0.
72-
terminal_newline <- !identical(attr(source_expression$lines, "terminal_newline", exact = TRUE), FALSE)
71+
terminal_newline <- !isFALSE(attr(source_expression$lines, "terminal_newline", exact = TRUE))
7372

7473
e <- NULL
7574
source_expression$lines <- extract_r_source(
@@ -493,19 +492,6 @@ get_source_expression <- function(source_expression, error = identity) {
493492
error = error
494493
)
495494

496-
# TODO: Remove when minimum R version is bumped to > 3.5
497-
#
498-
# This needs to be done twice to avoid a bug fixed in R 3.4.4
499-
# https://bugs.r-project.org/bugzilla/show_bug.cgi?id=16041
500-
parsed_content <- tryCatch(
501-
parse(
502-
text = source_expression$content,
503-
srcfile = source_expression,
504-
keep.source = TRUE
505-
),
506-
error = error
507-
)
508-
509495
if (inherits(parsed_content, c("error", "lint"))) {
510496
assign("e", parsed_content, envir = parent.frame())
511497
parse_error <- TRUE

R/namespace.R

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,7 @@ is_s3_generic <- function(fun) {
8585

8686
.base_s3_generics <- unique(c(
8787
names(.knownS3Generics),
88-
if (getRversion() >= "3.5.0") {
89-
.S3_methods_table[, 1L]
90-
} else {
91-
# R < 3.5.0 doesn't provide .S3_methods_table
92-
# fallback: search baseenv() for generic methods
93-
imported_s3_generics(data.frame(pkg = "base", fun = ls(baseenv()), stringsAsFactors = FALSE))$fun
94-
},
88+
.S3_methods_table[, 1L],
9589
# Contains S3 generic groups, see ?base::groupGeneric and src/library/base/R/zzz.R
9690
ls(.GenericArgsEnv)
9791
))

R/nonportable_path_linter.R

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,19 @@
22
#'
33
#' Check that [file.path()] is used to construct safe and portable paths.
44
#'
5+
#' @examples
6+
#' # will produce lints
7+
#' lint(
8+
#' text = "'abcdefg/hijklmnop/qrst/uv/wxyz'",
9+
#' linters = nonportable_path_linter()
10+
#' )
11+
#'
12+
#' # okay
13+
#' lint(
14+
#' text = "file.path('abcdefg', 'hijklmnop', 'qrst', 'uv', 'wxyz')",
15+
#' linters = nonportable_path_linter()
16+
#' )
17+
#'
518
#' @inheritParams absolute_path_linter
619
#' @evalRd rd_tags("nonportable_path_linter")
720
#' @seealso

R/sample_int_linter.R

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,34 @@
33
#' [sample.int()] is preferable to `sample()` for the case of sampling numbers
44
#' between 1 and `n`. `sample` calls `sample.int()` "under the hood".
55
#'
6+
#' @examples
7+
#' # will produce lints
8+
#' lint(
9+
#' text = "sample(1:10, 2)",
10+
#' linters = sample_int_linter()
11+
#' )
12+
#'
13+
#' lint(
14+
#' text = "sample(seq(4), 2)",
15+
#' linters = sample_int_linter()
16+
#' )
17+
#'
18+
#' lint(
19+
#' text = "sample(seq_len(8), 2)",
20+
#' linters = sample_int_linter()
21+
#' )
22+
#'
23+
#' # okay
24+
#' lint(
25+
#' text = "sample(seq(1, 5, by = 2), 2)",
26+
#' linters = sample_int_linter()
27+
#' )
28+
#'
29+
#' lint(
30+
#' text = "sample(letters, 2)",
31+
#' linters = sample_int_linter()
32+
#' )
33+
#'
634
#' @evalRd rd_tags("sample_int_linter")
735
#' @seealso [linters] for a complete list of linters available in lintr.
836
#' @export

R/scalar_in_linter.R

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,24 @@
77
#' `scalar %in% vector` is OK, because the alternative (`any(vector == scalar)`)
88
#' is more circuitous & potentially less clear.
99
#'
10+
#' @examples
11+
#' # will produce lints
12+
#' lint(
13+
#' text = "x %in% 1L",
14+
#' linters = scalar_in_linter()
15+
#' )
16+
#'
17+
#' lint(
18+
#' text = "x %chin% 'a'",
19+
#' linters = scalar_in_linter()
20+
#' )
21+
#'
22+
#' # okay
23+
#' lint(
24+
#' text = "x %in% 1:10",
25+
#' linters = scalar_in_linter()
26+
#' )
27+
#'
1028
#' @evalRd rd_tags("scalar_in_linter")
1129
#' @seealso [linters] for a complete list of linters available in lintr.
1230
#' @export

R/stopifnot_all_linter.R

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,29 @@
33
#' `stopifnot(A)` actually checks `all(A)` "under the hood" if `A` is a vector,
44
#' and produces a better error message than `stopifnot(all(A))` does.
55
#'
6+
#' @examples
7+
#' # will produce lints
8+
#' lint(
9+
#' text = "stopifnot(all(x > 0))",
10+
#' linters = stopifnot_all_linter()
11+
#' )
12+
#'
13+
#' lint(
14+
#' text = "stopifnot(y > 3, all(x < 0))",
15+
#' linters = stopifnot_all_linter()
16+
#' )
17+
#'
18+
#' # okay
19+
#' lint(
20+
#' text = "stopifnot(is.null(x) || all(x > 0))",
21+
#' linters = stopifnot_all_linter()
22+
#' )
23+
#'
24+
#' lint(
25+
#' text = "assert_that(all(x > 0))",
26+
#' linters = stopifnot_all_linter()
27+
#' )
28+
#'
629
#' @evalRd rd_tags("stopifnot_all_linter")
730
#' @seealso [linters] for a complete list of linters available in lintr.
831
#' @export

R/terminal_close_linter.R

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,37 @@
33
#' Functions that end in `close(x)` are almost always better written by using
44
#' `on.exit(close(x))` close to where `x` is defined and/or opened.
55
#'
6+
#' @examples
7+
#' # will produce lints
8+
#' code <- paste(
9+
#' "f <- function(fl) {",
10+
#' " conn <- file(fl, open = 'r')",
11+
#' " readLines(conn)",
12+
#' " close(conn)",
13+
#' "}",
14+
#' sep = "\n"
15+
#' )
16+
#' writeLines(code)
17+
#' lint(
18+
#' text = code,
19+
#' linters = terminal_close_linter()
20+
#' )
21+
#'
22+
#' # okay
23+
#' code <- paste(
24+
#' "f <- function(fl) {",
25+
#' " conn <- file(fl, open = 'r')",
26+
#' " on.exit(close(conn))",
27+
#' " readLines(conn)",
28+
#' "}",
29+
#' sep = "\n"
30+
#' )
31+
#' writeLines(code)
32+
#' lint(
33+
#' text = code,
34+
#' linters = terminal_close_linter()
35+
#' )
36+
#'
637
#' @evalRd rd_tags("terminal_close_linter")
738
#' @seealso [linters] for a complete list of linters available in lintr.
839
#' @export

man/comparison_negation_linter.Rd

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

man/nonportable_path_linter.Rd

Lines changed: 14 additions & 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)