Nothing
#' Warn about invalid usage of `all.equal()`
#'
#' [all.equal()] returns `TRUE` in the absence of differences but return a
#' character string (not `FALSE`) in the presence of differences.
#' Usage of `all.equal()` without wrapping it in `isTRUE()` in `if` clauses, or
#' preceded by the negation operator `!`, are thus likely to generate unexpected
#' errors if the compared objects have differences.
#' An alternative is to use `identical()` to compare vector of strings or when
#' exact equality is expected.
#'
#' @examples
#' # lints
#' lint(
#' text = 'if (all.equal(a, b)) message("equal")',
#' linters = all_equal_linter()
#' )
#'
#' lint(
#' text = '!all.equal(a, b)',
#' linters = all_equal_linter()
#' )
#'
#' lint(
#' text = 'isFALSE(all.equal(a, b))',
#' linters = all_equal_linter()
#' )
#'
#' # okay
#' lint(
#' text = 'if (isTRUE(all.equal(a, b))) message("equal")',
#' linters = all_equal_linter()
#' )
#'
#' lint(
#' text = '!identical(a, b)',
#' linters = all_equal_linter()
#' )
#'
#' lint(
#' text = "!isTRUE(all.equal(a, b))",
#' linters = all_equal_linter()
#' )
#'
#' @evalRd rd_tags("all_equal_linter")
#' @seealso [linters] for a complete list of linters available in lintr.
#' @export
all_equal_linter <- function() {
Linter(linter_level = "expression", function(source_expression) {
all_equal_calls <- source_expression$xml_find_function_calls("all.equal")
dangerous_unwrapped_all_equal <- xml_find_all(
all_equal_calls,
"parent::expr[
preceding-sibling::*[not(self::COMMENT)][2][self::IF or self::WHILE]
or preceding-sibling::*[not(self::COMMENT)][1][self::OP-EXCLAMATION]
]"
)
has_tolerance_arg <- !is.na(
xml_find_first(dangerous_unwrapped_all_equal, "SYMBOL_SUB[text() = 'tolerance']")
)
unwrapped_all_equal_lints <- xml_nodes_to_lints(
dangerous_unwrapped_all_equal,
source_expression = source_expression,
lint_message = ifelse(
has_tolerance_arg,
"Wrap all.equal() in isTRUE().",
"Wrap all.equal() in isTRUE(), or replace it by identical() if no tolerance is required."
),
type = "warning"
)
is_false_all_equal <- xml_find_all(
all_equal_calls,
"parent::expr[preceding-sibling::expr[1]/SYMBOL_FUNCTION_CALL/text() = 'isFALSE']"
)
is_false_all_equal_lints <- xml_nodes_to_lints(
is_false_all_equal,
source_expression = source_expression,
lint_message =
"Use !isTRUE() to check for differences in all.equal(). isFALSE(all.equal()) always returns FALSE.",
type = "warning"
)
c(unwrapped_all_equal_lints, is_false_all_equal_lints)
})
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.