Skip to content

Commit

Permalink
Merge branch 'main' into doc_getting_help
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelChirico authored Dec 20, 2022
2 parents a7dca01 + 7657984 commit 99bb9b6
Show file tree
Hide file tree
Showing 109 changed files with 1,067 additions and 435 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/R-CMD-check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ jobs:

- uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: any::rcmdcheck
extra-packages: |
any::rcmdcheck
bookdown=?ignore-before-r=3.5.0
needs: check

- uses: r-lib/actions/check-r-package@v2
Expand Down
2 changes: 1 addition & 1 deletion .lintr_new
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ linters: linters_with_defaults(
strings_as_factors_linter(),
unnecessary_nested_if_linter(),
unnecessary_lambda_linter(),
unneeded_concatenation_linter(allow_single_expression = FALSE),
unnecessary_concatenation_linter(allow_single_expression = FALSE),
yoda_test_linter()
)
exclusions: list(
Expand Down
7 changes: 4 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Config/Needs/website: tidyverse/tidytemplate
Config/testthat/edition: 3
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.2.2
RoxygenNote: 7.2.3
Collate:
'T_and_F_symbol_linter.R'
'utils.R'
Expand Down Expand Up @@ -157,13 +157,13 @@ Collate:
'system_file_linter.R'
'trailing_blank_lines_linter.R'
'trailing_whitespace_linter.R'
'tree-utils.R'
'tree_utils.R'
'undesirable_function_linter.R'
'undesirable_operator_linter.R'
'unnecessary_concatenation_linter.R'
'unnecessary_lambda_linter.R'
'unnecessary_nested_if_linter.R'
'unnecessary_placeholder_linter.R'
'unneeded_concatenation_linter.R'
'unreachable_code_linter.R'
'unused_import_linter.R'
'use_lintr.R'
Expand All @@ -174,3 +174,4 @@ Collate:
'xp_utils.R'
'yoda_test_linter.R'
'zzz.R'
Language: en-US
2 changes: 2 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export(Lint)
export(Linter)
export(T_and_F_symbol_linter)
export(absolute_path_linter)
export(all_linters)
export(all_undesirable_functions)
export(all_undesirable_operators)
export(any_duplicated_linter)
Expand Down Expand Up @@ -123,6 +124,7 @@ export(trailing_blank_lines_linter)
export(trailing_whitespace_linter)
export(undesirable_function_linter)
export(undesirable_operator_linter)
export(unnecessary_concatenation_linter)
export(unnecessary_lambda_linter)
export(unnecessary_nested_if_linter)
export(unnecessary_placeholder_linter)
Expand Down
11 changes: 9 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Bug fixes

* `fixed_regex_linter()` no longer fails with regular expression pattern `"\\;"` (#1545, @IndrajeetPatil).
* `fixed_regex_linter()` is more robust to errors stemming from unrecognized escapes (#1545, #1845, @IndrajeetPatil).

* `get_source_expressions()` can handle Sweave/Rmarkdown documents with reference chunks like `<<ref_file>>` (#779, @MichaelChirico).
Note that these are simply skipped, rather than attempting to retrieve the reference and also lint it.
Expand All @@ -11,7 +11,7 @@

* `object_usage_linter()` no longer silently ignores usage warnings that don't contain a quoted name (#1714, @AshesITR)

* `namespace_linter()` correctly recognizes backticked operators to be exported from respectives namespaces (like `` rlang::`%||%` ``) (#1752, @IndrajeetPatil)
* `namespace_linter()` correctly recognizes backticked operators to be exported from respective namespaces (like `` rlang::`%||%` ``) (#1752, @IndrajeetPatil)

* `lint_package()` correctly finds a package from within a subdir if the `path` points to anywhere within the package (#1759, @AshesITR)

Expand All @@ -24,6 +24,8 @@

* Row names for `available_linters()` data frame are now contiguous (#1781, @IndrajeetPatil).

* `object_name_linter()` allows all S3 group Generics (see `?base::groupGeneric`) and S3 generics defined in a different file in the same package (#1808, #1841, @AshesITR)

## Changes to defaults

* Set the default for the `except` argument in `duplicate_argument_linter()` to `c("mutate", "transmute")`.
Expand All @@ -44,6 +46,9 @@

* The new `indentation_linter()` is part of the default linters. See "New linters" for more details.

* For naming consistency, `unneeded_concatenation_linter()` has been deprecated in favor of
`unnecessary_concatenation_linter()` (#1797, @IndrajeetPatil).

## New and improved features

* New `get_r_string()` helper to get the R-equivalent value of a string, especially useful for R-4-style raw strings.
Expand Down Expand Up @@ -86,6 +91,8 @@

* Added `format()` functions for `lint` and `lints` (#1784, @AshesITR)

* `all_linters()` function provides an easy way to access all available linters (#1843, @IndrajeetPatil)

### New linters

* `unnecessary_lambda_linter()`: detect unnecessary lambdas (anonymous functions), e.g.
Expand Down
4 changes: 2 additions & 2 deletions R/T_and_F_symbol_linter.R
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
#'
#' @evalRd rd_tags("T_and_F_symbol_linter")
#' @seealso
#' [linters] for a complete list of linters available in lintr. \cr
#' <https://style.tidyverse.org/syntax.html#logical-vectors>
#' - [linters] for a complete list of linters available in lintr.
#' - <https://style.tidyverse.org/syntax.html#logical-vectors>
#' @export
T_and_F_symbol_linter <- function() { # nolint: object_name.
xpath <- paste0(
Expand Down
5 changes: 3 additions & 2 deletions R/absolute_path_linter.R
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@
#' )
#'
#' @evalRd rd_tags("absolute_path_linter")
#' @seealso [linters] for a complete list of linters available in lintr. \cr
#' [nonportable_path_linter()]
#' @seealso
#' - [linters] for a complete list of linters available in lintr.
#' - [nonportable_path_linter()]
#' @export
absolute_path_linter <- function(lax = TRUE) {
path_linter_factory(
Expand Down
4 changes: 2 additions & 2 deletions R/addins.R
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# nocov start
addin_lint <- function() {
if (!requireNamespace("rstudioapi", quietly = TRUE)) {
stop("'rstudioapi' is required for add-ins.") # nocov
stop("'rstudioapi' is required for add-ins.")
}
filename <- rstudioapi::getSourceEditorContext()
if (filename$path == "") {
Expand All @@ -27,7 +27,7 @@ addin_lint <- function() {

addin_lint_package <- function() {
if (!requireNamespace("rstudioapi", quietly = TRUE)) {
stop("'rstudioapi' is required for add-ins.") # nocov
stop("'rstudioapi' is required for add-ins.")
}
project <- rstudioapi::getActiveProject()
project_path <- if (is.null(project)) getwd() else project
Expand Down
4 changes: 2 additions & 2 deletions R/assignment_linter.R
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@
#'
#' @evalRd rd_tags("assignment_linter")
#' @seealso
#' [linters] for a complete list of linters available in lintr. \cr
#' <https://style.tidyverse.org/syntax.html#assignment-1>
#' - [linters] for a complete list of linters available in lintr.
#' - <https://style.tidyverse.org/syntax.html#assignment-1>
#' @export
assignment_linter <- function(allow_cascading_assign = TRUE, allow_right_assign = FALSE, allow_trailing = TRUE) {
trailing_assign_xpath <- paste(
Expand Down
7 changes: 4 additions & 3 deletions R/brace_linter.R
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@
#' linters = brace_linter(allow_single_line = TRUE)
#' )
#' @evalRd rd_tags("brace_linter")
#' @seealso [linters] for a complete list of linters available in lintr. \cr
#' <https://style.tidyverse.org/syntax.html#indenting> \cr
#' <https://style.tidyverse.org/syntax.html#if-statements>
#' @seealso
#' - [linters] for a complete list of linters available in lintr.
#' - <https://style.tidyverse.org/syntax.html#indenting>
#' - <https://style.tidyverse.org/syntax.html#if-statements>
#' @export
brace_linter <- function(allow_single_line = FALSE) {
xp_cond_open <- xp_and(c(
Expand Down
4 changes: 2 additions & 2 deletions R/commas_linter.R
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@
#'
#' @evalRd rd_tags("commas_linter")
#' @seealso
#' [linters] for a complete list of linters available in lintr. \cr
#' <https://style.tidyverse.org/syntax.html#commas>
#' - [linters] for a complete list of linters available in lintr.
#' - <https://style.tidyverse.org/syntax.html#commas>
#' @export
commas_linter <- function() {
# conditions are in carefully-chosen order for performance --
Expand Down
4 changes: 2 additions & 2 deletions R/deprecated.R
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ lintr_deprecated <- function(old, new = NULL, version = NULL,
type = "Function") {
msg <- c(
c(type, " ", old, " was deprecated"),
if (length(version)) {
if (length(version) > 0L) {
c(" in lintr version ", version)
},
". ",
if (length(new)) {
if (length(new) > 0L) {
c("Use ", new, " instead.")
}
)
Expand Down
2 changes: 1 addition & 1 deletion R/empty_assignment_linter.R
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#' Block assignment of `{}`
#'
#' Assignment of `{}` is the same as assignment of `NULL`; use the latter
#' for clarity. Closely related: [unneeded_concatenation_linter()].
#' for clarity. Closely related: [unnecessary_concatenation_linter()].
#'
#' @examples
#' # will produce lints
Expand Down
2 changes: 1 addition & 1 deletion R/expect_lint.R
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#' is not recommended for new code.
#' @param ... arguments passed to [lint()], e.g. the linters or cache to use.
#' @param file if not `NULL`, read content from the specified file rather than from `content`.
#' @param language temporarily override Rs `LANGUAGE` envvar, controlling localisation of base R error messages.
#' @param language temporarily override Rs `LANGUAGE` envvar, controlling localization of base R error messages.
#' This makes testing them reproducible on all systems irrespective of their native R language setting.
#' @return `NULL`, invisibly.
#' @examples
Expand Down
5 changes: 3 additions & 2 deletions R/expect_s3_class_linter.R
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@
#' )
#'
#' @evalRd rd_tags("expect_s3_class_linter")
#' @seealso [linters] for a complete list of linters available in lintr. \cr
#' [expect_s4_class_linter()]
#' @seealso
#' - [linters] for a complete list of linters available in lintr.
#' - [expect_s4_class_linter()]
#' @export
expect_s3_class_linter <- function() {
# (1) expect_{equal,identical}(class(x), C)
Expand Down
5 changes: 3 additions & 2 deletions R/expect_s4_class_linter.R
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@
#' )
#'
#' @evalRd rd_tags("expect_s4_class_linter")
#' @seealso [linters] for a complete list of linters available in lintr. \cr
#' [expect_s3_class_linter()]
#' @seealso
#' - [linters] for a complete list of linters available in lintr.
#' - [expect_s3_class_linter()]
#' @export
expect_s4_class_linter <- function() {
# require 2 expressions because methods::is(x) alone is a valid call, even
Expand Down
10 changes: 7 additions & 3 deletions R/fixed_regex_linter.R
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,12 @@ fixed_regex_linter <- function() {

# regular expression pattern is the second argument
pos_2_regex_funs <- xp_text_in_table(c(
"strsplit", "tstrsplit",
# stringr functions. even though the user action is different
# base functions.
"strsplit",
# data.table functions.
"tstrsplit",
# stringr functions.
# even though the user action is different
# (setting fixed=TRUE vs. wrapping stringr::fixed()),
# detection of the lint is the same
"str_count", "str_detect", "str_ends", "str_extract", "str_extract_all",
Expand Down Expand Up @@ -231,7 +235,7 @@ get_token_replacement <- function(token_content, token_type) {
token_content
}
} else { # char_escape token
if (rex::re_matches(token_content, rex::rex("\\", one_of("^${}().*+?|[]\\<>:;")))) {
if (rex::re_matches(token_content, rex::rex("\\", one_of("^${}().*+?|[]\\<>=:;/_-!@#%&,~")))) {
substr(token_content, start = 2L, stop = nchar(token_content))
} else {
eval(parse(text = paste0('"', token_content, '"')))
Expand Down
4 changes: 2 additions & 2 deletions R/function_argument_linter.R
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@
#'
#' @evalRd rd_tags("function_argument_linter")
#' @seealso
#' [linters] for a complete list of linters available in lintr. \cr
#' <https://design.tidyverse.org/args-data-details.html>
#' - [linters] for a complete list of linters available in lintr.
#' - <https://design.tidyverse.org/args-data-details.html>
#' @export
function_argument_linter <- function() {
xpath <- paste(collapse = " | ", glue::glue("
Expand Down
6 changes: 3 additions & 3 deletions R/function_left_parentheses_linter.R
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@
#'
#' @evalRd rd_tags("function_left_parentheses_linter")
#' @seealso
#' [linters] for a complete list of linters available in lintr. \cr
#' <https://style.tidyverse.org/syntax.html#parentheses> \cr
#' [spaces_left_parentheses_linter()]
#' - [linters] for a complete list of linters available in lintr.
#' - <https://style.tidyverse.org/syntax.html#parentheses>
#' - [spaces_left_parentheses_linter()]
#' @export
function_left_parentheses_linter <- function() { # nolint: object_length.
xpath <- "
Expand Down
44 changes: 13 additions & 31 deletions R/get_source_expressions.R
Original file line number Diff line number Diff line change
Expand Up @@ -483,43 +483,46 @@ get_single_source_expression <- function(loc,
get_source_expression <- function(source_expression, error = identity) {
parse_error <- FALSE

tryCatch(
source_expression$parsed_content <- parse(
parsed_content <- tryCatch(
parse(
text = source_expression$content,
srcfile = source_expression,
keep.source = TRUE
),
error = error
)

# This needs to be done twice to avoid
# TODO: Remove when minimum R version is bumped to > 3.5
#
# This needs to be done twice to avoid a bug fixed in R 3.4.4
# https://bugs.r-project.org/bugzilla/show_bug.cgi?id=16041
e <- tryCatch(
source_expression$parsed_content <- parse(
parsed_content <- tryCatch(
parse(
text = source_expression$content,
srcfile = source_expression,
keep.source = TRUE
),
error = error
)

if (inherits(e, c("error", "lint"))) {
assign("e", e, envir = parent.frame())
if (inherits(parsed_content, c("error", "lint"))) {
assign("e", parsed_content, envir = parent.frame())
parse_error <- TRUE
}

# Triggers an error if the lines contain invalid characters.
e <- tryCatch(
parsed_content <- tryCatch(
nchar(source_expression$content, type = "chars"),
error = error
)

if (inherits(e, c("error", "lint"))) {
if (inherits(parsed_content, c("error", "lint"))) {
# Let parse errors take precedence over encoding problems
if (!parse_error) assign("e", e, envir = parent.frame())
if (!parse_error) assign("e", parsed_content, envir = parent.frame())
return() # parsed_content is unreliable if encoding is invalid
}

source_expression$parsed_content <- parsed_content
fix_octal_escapes(fix_eq_assigns(fix_tab_indentations(source_expression)), source_expression$lines)
}

Expand All @@ -532,27 +535,6 @@ get_newline_locs <- function(x) {
)
}

find_line_fun <- function(content, newline_locs) {
function(line_number) {
warning(
"find_line is deprecated and will soon be removed. ",
"XPath logic and xml_nodes_to_lints() are usually preferable"
)
which(newline_locs >= line_number)[1L] - 1L
}
}

find_column_fun <- function(content, newline_locs) {
function(line_number) {
warning(
"find_column is deprecated and will soon be removed. ",
"XPath logic and xml_nodes_to_lints() are usually preferable"
)
matched_line_number <- which(newline_locs >= line_number)[1L] - 1L
line_number - newline_locs[matched_line_number]
}
}

# Fix column numbers when there are tabs
# getParseData() counts 1 tab as a variable number of spaces instead of one:
# https://github.com/wch/r-source/blame/e7401b68ab0e032fce3e376aaca9a5431619b2b4/src/main/gram.y#L512
Expand Down
2 changes: 1 addition & 1 deletion R/implicit_assignment_linter.R
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ implicit_assignment_linter <- function(except = c(
"expect_output", "expect_silent",
"local", "quo", "quos", "quote", "test_that"
)) {
stopifnot(is.character(except))
stopifnot(is.null(except) || is.character(except))

if (length(except) > 0L) {
exceptions <- xp_text_in_table(except)
Expand Down
4 changes: 2 additions & 2 deletions R/infix_spaces_linter.R
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ infix_overload <- data.frame(
#'
#' @evalRd rd_tags("infix_spaces_linter")
#' @seealso
#' [linters] for a complete list of linters available in lintr. \cr
#' <https://style.tidyverse.org/syntax.html#infix-operators>
#' - [linters] for a complete list of linters available in lintr.
#' - <https://style.tidyverse.org/syntax.html#infix-operators>
#' @export
infix_spaces_linter <- function(exclude_operators = NULL, allow_multiple_spaces = TRUE) {
if (allow_multiple_spaces) {
Expand Down
Loading

0 comments on commit 99bb9b6

Please sign in to comment.