From 32a2229c2341326f1d14bb3b049426a014e53d98 Mon Sep 17 00:00:00 2001 From: Michael Chirico Date: Sun, 27 Oct 2024 09:45:46 -0700 Subject: [PATCH] re_matches_logical helper ensures logical output of re_matches_logical --- R/expect_lint.R | 8 +------- R/lintr-package.R | 2 +- R/object_name_linter.R | 7 +------ R/return_linter.R | 3 ++- R/todo_comment_linter.R | 4 ++-- R/unreachable_code_linter.R | 2 +- R/utils.R | 11 +++++++++++ 7 files changed, 19 insertions(+), 18 deletions(-) diff --git a/R/expect_lint.R b/R/expect_lint.R index 7bc1b65fd..78658ffc0 100644 --- a/R/expect_lint.R +++ b/R/expect_lint.R @@ -105,16 +105,10 @@ expect_lint <- function(content, checks, ..., file = NULL, language = "en") { ) # deparse ensures that NULL, list(), etc are handled gracefully ok <- if (field == "message") { - re_matches(value, check) + re_matches_logical(value, check) } else { isTRUE(all.equal(value, check)) } - if (!is.logical(ok)) { - cli_abort(c( - x = "Invalid regex result. Did you mistakenly have a capture group in the regex?", - i = "You can match parentheses with a character class, i.e. inside `[]`." - )) - } testthat::expect(ok, msg) }) }, diff --git a/R/lintr-package.R b/R/lintr-package.R index 70f8d0d11..d453bcab1 100644 --- a/R/lintr-package.R +++ b/R/lintr-package.R @@ -11,7 +11,7 @@ #' @importFrom cli cli_inform cli_abort cli_warn #' @importFrom glue glue glue_collapse #' @importFrom rex rex regex re_matches re_substitutes character_class -#' @importFrom stats na.omit +#' @importFrom stats complete.cases na.omit #' @importFrom tools R_user_dir #' @importFrom utils capture.output getParseData getTxtProgressBar globalVariables head relist #' setTxtProgressBar tail txtProgressBar diff --git a/R/object_name_linter.R b/R/object_name_linter.R index 54cbb523d..ba9583039 100644 --- a/R/object_name_linter.R +++ b/R/object_name_linter.R @@ -146,13 +146,8 @@ object_name_linter <- function(styles = c("snake_case", "symbols"), regexes = ch } check_style <- function(nms, style, generics = character()) { - conforming <- re_matches(nms, style) + conforming <- re_matches_logical(nms, style) - # style has capture group(s) - if (is.data.frame(conforming)) { - # if any group is missing, all groups are missing, so just check the first column - conforming <- !is.na(conforming[[1L]]) - } # mark empty or NA names as conforming conforming <- is.na(nms) | !nzchar(nms) | conforming diff --git a/R/return_linter.R b/R/return_linter.R index a0e1c245f..d0bc75d91 100644 --- a/R/return_linter.R +++ b/R/return_linter.R @@ -147,7 +147,8 @@ return_linter <- function( xml <- source_expression$xml_parsed_content if (defer_except) { assigned_functions <- xml_text(xml_find_all(xml, function_name_xpath)) - except <- union(except, assigned_functions[re_matches(assigned_functions, except_regex)]) + except <- + union(except, assigned_functions[re_matches_logical(assigned_functions, except_regex)]) except_xpath <- glue(except_xpath_fmt, except = except) body_xpath <- glue(body_xpath_fmt, except_xpath = except_xpath) } diff --git a/R/todo_comment_linter.R b/R/todo_comment_linter.R index 16e1de05f..5d6d94282 100644 --- a/R/todo_comment_linter.R +++ b/R/todo_comment_linter.R @@ -57,9 +57,9 @@ todo_comment_linter <- function(todo = c("todo", "fixme"), except_regex = NULL) comment_expr <- xml_find_all(xml, "//COMMENT") comment_text <- xml_text(comment_expr) - invalid_todo <- re_matches(comment_text, todo_comment_regex, ignore.case = TRUE) + invalid_todo <- re_matches_logical(comment_text, todo_comment_regex, ignore.case = TRUE) if (!is.null(valid_todo_regex)) { - invalid_todo <- invalid_todo & !re_matches(comment_text, valid_todo_regex) + invalid_todo <- invalid_todo & !re_matches_logical(comment_text, valid_todo_regex) } xml_nodes_to_lints( diff --git a/R/unreachable_code_linter.R b/R/unreachable_code_linter.R index 124b5a12f..f2e9f8d56 100644 --- a/R/unreachable_code_linter.R +++ b/R/unreachable_code_linter.R @@ -130,7 +130,7 @@ unreachable_code_linter <- function(allow_comment_regex = getOption("covr.exclud drop_valid_comments <- function(expr, valid_comment_re) { is_valid_comment <- xml2::xml_name(expr) == "COMMENT" & - re_matches(xml_text(expr), valid_comment_re) + re_matches_logical(xml_text(expr), valid_comment_re) expr[!is_valid_comment] } diff --git a/R/utils.R b/R/utils.R index d23fc8902..1c1e3296d 100644 --- a/R/utils.R +++ b/R/utils.R @@ -195,6 +195,17 @@ release_bullets <- function() { platform_independent_order <- function(x) order(tolower(x), method = "radix") platform_independent_sort <- function(x) x[platform_independent_order(x)] +#' re_matches with type-stable logical output +#' TODO(r-lib/rex#94): Use re_matches() option directly & deprecate this. +#' @noRd +re_matches_logical <- function(x, regex, ...) { + res <- re_matches(x, regex, ...) + if (is.data.frame(res)) { + res <- complete.cases(res) + } + res +} + #' Extract text from `STR_CONST` nodes #' #' Convert `STR_CONST` `text()` values into R strings. This is useful to account for arbitrary