diff --git a/R/function_argument_linter.R b/R/function_argument_linter.R index 936a14fb0..63cb5da32 100644 --- a/R/function_argument_linter.R +++ b/R/function_argument_linter.R @@ -46,14 +46,14 @@ #' - #' @export function_argument_linter <- function() { - xpath <- paste(collapse = " | ", glue::glue(" - //{c('FUNCTION', 'OP-LAMBDA')} + xpath <- " + (//FUNCTION | //OP-LAMBDA) /following-sibling::EQ_FORMALS[1] /following-sibling::SYMBOL_FORMALS[ text() != '...' and not(following-sibling::*[not(self::COMMENT)][1][self::EQ_FORMALS]) ] - ")) + " Linter(function(source_expression) { if (!is_lint_level(source_expression, "expression")) { diff --git a/R/indentation_linter.R b/R/indentation_linter.R index 9f98a6e2d..5d369f4ab 100644 --- a/R/indentation_linter.R +++ b/R/indentation_linter.R @@ -175,15 +175,16 @@ indentation_linter <- function(indent = 2L, hanging_indent_style = c("tidy", "al ")" ) + global_nodes <- function(nodes) paste0("//", nodes, collapse = "|") xp_indent_changes <- paste( c( glue::glue("//{paren_tokens_left}[not(@line1 = following-sibling::expr[ @line2 > @line1 and ({xp_or(paste0('descendant::', paren_tokens_left, '[', xp_last_on_line, ']'))}) ]/@line1)]"), - glue::glue("//{infix_tokens}[{xp_last_on_line}{infix_condition}]"), - glue::glue("//{no_paren_keywords}[{xp_last_on_line}]"), - glue::glue("//{keyword_tokens}/following-sibling::OP-RIGHT-PAREN[ + glue::glue("({ global_nodes(infix_tokens) })[{xp_last_on_line}{infix_condition}]"), + glue::glue("({ global_nodes(no_paren_keywords) })[{xp_last_on_line}]"), + glue::glue("({ global_nodes(keyword_tokens) })/following-sibling::OP-RIGHT-PAREN[ {xp_last_on_line} and not(following-sibling::expr[1][OP-LEFT-BRACE]) ]") diff --git a/R/infix_spaces_linter.R b/R/infix_spaces_linter.R index 8dcdcc0fb..2569a2f56 100644 --- a/R/infix_spaces_linter.R +++ b/R/infix_spaces_linter.R @@ -147,7 +147,8 @@ infix_spaces_linter <- function(exclude_operators = NULL, allow_multiple_spaces # NB: parent::*[count(expr | SYMBOL_SUB)) > 1] for the unary case, e.g. x[-1] # SYMBOL_SUB for case with missing argument like alist(a =) # NB: the last not() disables lints inside box::use() declarations - xpath <- paste(collapse = "|", glue::glue("//{infix_tokens}[ + global_xpath <- paste0("//", infix_tokens, collapse = "|") + xpath <- glue::glue("({global_xpath})[ parent::*[count(expr | SYMBOL_SUB) > 1] and ( ( @@ -166,7 +167,7 @@ infix_spaces_linter <- function(exclude_operators = NULL, allow_multiple_spaces ] ] ) - ]")) + ]") Linter(function(source_expression) { if (!is_lint_level(source_expression, "expression")) { diff --git a/R/pipe_continuation_linter.R b/R/pipe_continuation_linter.R index 4580637d4..6f6463f5e 100644 --- a/R/pipe_continuation_linter.R +++ b/R/pipe_continuation_linter.R @@ -53,19 +53,17 @@ pipe_continuation_linter <- function() { # Where a single-line pipeline is nested inside a larger expression # e.g. inside a function definition), the outer expression can span multiple lines # without throwing a lint. - - pipe_conditions <- " + preceding_pipe <- "preceding-sibling::expr[1]/descendant::*[self::SPECIAL[text() = '%>%'] or self::PIPE]" + xpath <- glue::glue(" + (//PIPE | //SPECIAL[text() = '%>%'])[ parent::expr[@line1 < @line2] - and preceding-sibling::expr/descendant-or-self::*[self::SPECIAL[text() = '%>%'] or self::PIPE] + and {preceding_pipe} and ( - preceding-sibling::expr/descendant-or-self::expr/@line2 - = following-sibling::expr/descendant-or-self::expr/@line1 - or @line1 = preceding-sibling::expr/descendant-or-self::*[self::SPECIAL[text() = '%>%'] or self::PIPE]/@line1 + preceding-sibling::expr[1]/descendant-or-self::expr/@line2 + = following-sibling::expr[1]/descendant-or-self::expr/@line1 + or @line1 = {preceding_pipe}/@line1 ) - " - xpath <- glue::glue(" - //SPECIAL[text() = '%>%' and {pipe_conditions} ] - | //PIPE[ {pipe_conditions} ] + ] ") Linter(function(source_expression) { diff --git a/R/redundant_equals_linter.R b/R/redundant_equals_linter.R index d23811f17..274cde30a 100644 --- a/R/redundant_equals_linter.R +++ b/R/redundant_equals_linter.R @@ -36,11 +36,12 @@ #' - [outer_negation_linter()] #' @export redundant_equals_linter <- function() { - xpath <- paste0( - c("//EQ", "//NE"), - "/parent::expr/expr[NUM_CONST[text() = 'TRUE' or text() = 'FALSE']]/parent::expr", - collapse = " | " - ) + xpath <- " + (//EQ | //NE) + /parent::expr + /expr[NUM_CONST[text() = 'TRUE' or text() = 'FALSE']] + /parent::expr + " Linter(function(source_expression) { if (!is_lint_level(source_expression, "expression")) { diff --git a/R/vector_logic_linter.R b/R/vector_logic_linter.R index 388ed99b9..f50149d1a 100644 --- a/R/vector_logic_linter.R +++ b/R/vector_logic_linter.R @@ -60,8 +60,8 @@ vector_logic_linter <- function() { # ... # # we _don't_ want to match anything on the second expr, hence this - xpath_parts <- glue::glue(" - //{ c('AND', 'OR') }[ + xpath <- " + (//AND | //OR)[ ancestor::expr[ not(preceding-sibling::OP-RIGHT-PAREN) and preceding-sibling::*[ @@ -75,8 +75,7 @@ vector_logic_linter <- function() { or preceding-sibling::OP-LEFT-BRACKET ]) ] - ") - xpath <- paste(xpath_parts, collapse = " | ") + " Linter(function(source_expression) { if (!is_lint_level(source_expression, "expression")) {