diff --git a/R/call_hierarchy.R b/R/call_hierarchy.R index c66b4333..61068ac8 100644 --- a/R/call_hierarchy.R +++ b/R/call_hierarchy.R @@ -301,7 +301,7 @@ call_hierarchy_incoming_calls_reply <- function(id, workspace, item) { line2 <- end_point$row + 1 col2 <- end_point$col - symbols <- xml_find_all(xdoc, + symbols <- xml_find_all_(xdoc, glue("//SYMBOL_FUNCTION_CALL[ ((@line1 = {line1} and @col1 >= {col1}) or @line1 > {line1}) and ((@line2 = {line2} and @col2 <= {col2}) or @line2 < {line2}) and @@ -375,7 +375,7 @@ call_hierarchy_incoming_calls_reply <- function(id, workspace, item) { } } - symbols <- xml_find_all(xdoc, + symbols <- xml_find_all_(xdoc, glue("//SYMBOL_FUNCTION_CALL[text() = '{token_quote}']", token_quote = token_quote)) if (!length(symbols)) next @@ -460,7 +460,7 @@ call_hierarchy_outgoing_calls_reply <- function(id, workspace, item) { line2 <- end_point$row + 1 col2 <- end_point$col - symbols <- xml_find_all(xdoc, + symbols <- xml_find_all_(xdoc, glue("//SYMBOL_FUNCTION_CALL[ ((@line1 = {line1} and @col1 >= {col1}) or @line1 > {line1}) and ((@line2 = {line2} and @col2 <= {col2}) or @line2 < {line2})]", diff --git a/R/class_index.R b/R/class_index.R index 2b859efe..f2a1dcb0 100644 --- a/R/class_index.R +++ b/R/class_index.R @@ -2,8 +2,8 @@ class_index_key <- function(type, name) paste(type, name, sep = "\r") # Parser XML has no namespaces. xml2's default namespace discovery walks the # whole document for every local query, turning class extraction quadratic. -class_xml_first <- function(node, xpath) xml_find_first(node, xpath, ns = character()) -class_xml_all <- function(node, xpath) xml_find_all(node, xpath, ns = character()) +class_xml_first <- function(node, xpath) xml_find_first_(node, xpath) +class_xml_all <- function(node, xpath) xml_find_all_(node, xpath) #' Decode inert class names and member names using R literal syntax #' @noRd @@ -47,7 +47,7 @@ class_xml_arguments <- function(node) { if (native || isTRUE(magrittr)) { lhs <- class_xml_first(operator, "preceding-sibling::expr[1]") placeholder <- vapply(arguments, function(argument) { - isTRUE(xml_find_lgl(argument, if (native) "boolean(PLACEHOLDER[parent::expr[count(*) = 1]])" else + isTRUE(xml_find_lgl_(argument, if (native) "boolean(PLACEHOLDER[parent::expr[count(*) = 1]])" else "boolean(SYMBOL[text() = '.' and parent::expr[count(*) = 1]])")) }, logical(1L)) if (any(placeholder)) arguments[placeholder] <- list(lhs) diff --git a/R/code_lens.R b/R/code_lens.R index f5d5f1b2..510bb286 100644 --- a/R/code_lens.R +++ b/R/code_lens.R @@ -38,7 +38,7 @@ function_call_locations <- function(workspace, symbol, context_uri = NULL, xdoc <- parse_data_xml(parse_data) if (is.null(xdoc)) next - nodes <- xml_find_all( + nodes <- xml_find_all_( xdoc, glue(paste0( "//SYMBOL_FUNCTION_CALL[text() = '{token_quote}' and ", diff --git a/R/color.R b/R/color.R index e85909a9..c2dac246 100644 --- a/R/color.R +++ b/R/color.R @@ -21,7 +21,7 @@ document_color_reply <- function(id, uri, workspace, document) { # Shortest color length: 3 (red, tan) # Longest color length: 20 (lightgoldenrodyellow) if (is.null(strings)) { - str_tokens <- xml_find_all(xdoc, "//STR_CONST[@line1=@line2 and @col2>@col1+3 and @col2<@col1+22]") + str_tokens <- xml_find_all_(xdoc, "//STR_CONST[@line1=@line2 and @col2>@col1+3 and @col2<@col1+22]") str_line1 <- as.integer(xml_attr(str_tokens, "line1")) str_col1 <- as.integer(xml_attr(str_tokens, "col1")) str_col2 <- as.integer(xml_attr(str_tokens, "col2")) diff --git a/R/completion.R b/R/completion.R index c31375f2..467436fb 100644 --- a/R/completion.R +++ b/R/completion.R @@ -366,7 +366,7 @@ arg_completion <- function(uri, workspace, point, token, funct, package = NULL, if (length(all_defs)) { last_def <- all_defs[[length(all_defs)]] func_line1 <- as.integer(xml_attr(last_def, "line1")) - args <- xml_text(xml_find_all(last_def, "SYMBOL_FORMALS")) + args <- xml_text(xml_find_all_(last_def, "SYMBOL_FORMALS")) token_args <- args[match_with(args, token)] token_data <- list( type = "parameter", @@ -875,7 +875,7 @@ scope_completion <- function(uri, workspace, token, point, in_lexical_scope <- function(nodes) { vapply(nodes, function(node) { - scope <- xml_find_first(node, "ancestor::expr[FUNCTION or OP-LAMBDA][1]") + scope <- xml_find_first_(node, "ancestor::expr[FUNCTION or OP-LAMBDA][1]") if (inherits(scope, "xml_missing")) return(TRUE) contains_point(list( line1 = as.integer(xml_attr(scope, "line1")), @@ -885,13 +885,13 @@ scope_completion <- function(uri, workspace, token, point, )) }, logical(1L)) } - scope_symbol_nodes <- xml_find_all(enclosing_scopes, + scope_symbol_nodes <- xml_find_all_(enclosing_scopes, scope_completion_symbols_xpath) scope_symbol_nodes <- scope_symbol_nodes[in_lexical_scope(scope_symbol_nodes)] scope_symbol_names <- xml_text(scope_symbol_nodes) scope_symbol_lines <- as.integer(xml_attr(scope_symbol_nodes, "line1")) - scope_funct_nodes <- xml_find_all(enclosing_scopes, + scope_funct_nodes <- xml_find_all_(enclosing_scopes, scope_completion_functs_xpath) scope_funct_nodes <- scope_funct_nodes[in_lexical_scope(scope_funct_nodes)] scope_funct_names <- xml_text(scope_funct_nodes) @@ -1085,7 +1085,7 @@ token_completion <- function(uri, workspace, token, exclude = NULL, limit = Inf) token_quote <- xml_single_quote(token) - symbols <- xml_text(xml_find_all( + symbols <- xml_text(xml_find_all_( xdoc, glue( "//SYMBOL[preceding-sibling::OP-DOLLAR and starts-with(text(),'{token_quote}')] | @@ -1095,7 +1095,7 @@ token_completion <- function(uri, workspace, token, exclude = NULL, limit = Inf) )) if (nzchar(token)) { - symbols <- c(symbols, xml_text(xml_find_all( + symbols <- c(symbols, xml_text(xml_find_all_( xdoc, glue( "//SYMBOL[starts-with(text(),'{token_quote}')] | diff --git a/R/definition.R b/R/definition.R index 58f03895..808a2761 100644 --- a/R/definition.R +++ b/R/definition.R @@ -72,7 +72,7 @@ definition_reply <- function(id, uri, workspace, document, point, logger$info("definition: ", token_name, token_text) if (token_name %in% c("SYMBOL", "SYMBOL_FUNCTION_CALL", "SYMBOL_FORMALS")) { # symbol - if (xml_find_lgl(token, "not(preceding-sibling::OP-DOLLAR)")) { + if (xml_find_lgl_(token, "not(preceding-sibling::OP-DOLLAR)")) { xpath <- glue(definition_xpath, row = row, start = token_start, end = token_end, token_quote = xml_single_quote(token_text)) diff --git a/R/folding.R b/R/folding.R index 2b050047..b291a762 100644 --- a/R/folding.R +++ b/R/folding.R @@ -6,7 +6,7 @@ FoldingRangeKind <- list( get_comment_folding_ranges <- function(xdoc, outline = NULL) { if (is.null(outline)) { - comments <- xml_find_all(xdoc, "//COMMENT") + comments <- xml_find_all_(xdoc, "//COMMENT") text <- xml_text(comments, trim = FALSE) lines <- as.integer(xml_attr(comments, "line1")) cols <- as.integer(xml_attr(comments, "col1")) @@ -80,13 +80,13 @@ get_document_blocks <- function(xdoc, outline = NULL) { if (is.null(xdoc)) { return(NULL) } - block_start <- xml_find_all(xdoc, "(//OP-LEFT-PAREN | //OP-LEFT-BRACKET | //OP-LEFT-BRACE)[parent::expr and + block_start <- xml_find_all_(xdoc, "(//OP-LEFT-PAREN | //OP-LEFT-BRACKET | //OP-LEFT-BRACE)[parent::expr and @line1 < (following-sibling::OP-RIGHT-PAREN | following-sibling::OP-RIGHT-BRACKET | following-sibling::OP-RIGHT-BRACE)/@line1]") if (!length(block_start)) { # prevent floating point comparision return(NULL) } - block_end <- xml_find_first(block_start, "following-sibling::OP-RIGHT-PAREN | following-sibling::OP-RIGHT-BRACKET | following-sibling::OP-RIGHT-BRACE") + block_end <- xml_find_first_(block_start, "following-sibling::OP-RIGHT-PAREN | following-sibling::OP-RIGHT-BRACKET | following-sibling::OP-RIGHT-BRACE") block_start_line <- as.integer(xml_attr(block_start, "line1")) block_end_line <- as.integer(xml_attr(block_end, "line1")) diff --git a/R/highlight.R b/R/highlight.R index 3962da7f..9de2a39c 100644 --- a/R/highlight.R +++ b/R/highlight.R @@ -91,15 +91,15 @@ document_highlight_reply <- function(id, uri, workspace, document, point) { tokens <- NULL if (token_name %in% c("SYMBOL", "SYMBOL_FUNCTION_CALL", "SYMBOL_FORMALS")) { - if (xml_find_lgl(token, "not(preceding-sibling::OP-DOLLAR)")) { + if (xml_find_lgl_(token, "not(preceding-sibling::OP-DOLLAR)")) { xpath <- glue(document_highlight_xpath, token_quote = token_quote) - tokens <- xml_find_all(xdoc, xpath) + tokens <- xml_find_all_(xdoc, xpath) } } else if (token_name %in% c( "SYMBOL_PACKAGE", "FUNCTION", "NUM_CONST", "STR_CONST")) { # Compare text directly: XML entities do not escape quotes # inside XPath string literals (for example, 'a string'). - tokens <- xml_find_all(xdoc, paste0("//", token_name)) + tokens <- xml_find_all_(xdoc, paste0("//", token_name)) tokens <- tokens[xml_text(tokens) == token_text] } diff --git a/R/hover.R b/R/hover.R index 367c3790..c722f254 100644 --- a/R/hover.R +++ b/R/hover.R @@ -105,14 +105,14 @@ hover_reply <- function(id, uri, workspace, document, point) { logger$info(token_name, token_text) if (token_name %in% c("SYMBOL", "SYMBOL_FUNCTION_CALL")) { # symbol - if (xml_find_lgl(token, "not(preceding-sibling::OP-DOLLAR)")) { + if (xml_find_lgl_(token, "not(preceding-sibling::OP-DOLLAR)")) { xpath <- glue(hover_xpath, row = row, start = token_start, end = token_end, token_quote = xml_single_quote(token_text)) all_defs <- xdoc_find_definitions(xdoc, row, col, token_text, xpath) if (length(all_defs)) { last_def <- all_defs[[length(all_defs)]] - def_func <- xml_find_first(last_def, + def_func <- xml_find_first_(last_def, "expr[(FUNCTION or OP-LAMBDA) and parent::*[LEFT_ASSIGN or RIGHT_ASSIGN or EQ_ASSIGN]]") if (length(def_func)) { func_line1 <- as.integer(xml_attr(def_func, "line1")) @@ -147,9 +147,9 @@ hover_reply <- function(id, uri, workspace, document, point) { } } else if (token_name == "SYMBOL_SUB") { # function parameter - funct <- xml_find_chr(token, "string(preceding-sibling::expr/SYMBOL_FUNCTION_CALL)") + funct <- xml_find_chr_(token, "string(preceding-sibling::expr/SYMBOL_FUNCTION_CALL)") if (nzchar(funct)) { - package <- xml_find_chr(token, "string(preceding-sibling::expr/SYMBOL_PACKAGE)") + package <- xml_find_chr_(token, "string(preceding-sibling::expr/SYMBOL_PACKAGE)") if (!nzchar(package)) { package <- NULL xpath <- glue(signature_xpath, row = row, @@ -187,7 +187,7 @@ hover_reply <- function(id, uri, workspace, document, point) { } } else if (token_name == "SYMBOL_FORMALS") { # function formals - funct <- xml_find_first(token, "parent::expr[FUNCTION or OP-LAMBDA]") + funct <- xml_find_first_(token, "parent::expr[FUNCTION or OP-LAMBDA]") func_line1 <- as.integer(xml_attr(funct, "line1")) doc_line1 <- detect_comments(document$content, func_line1 - 1) + 1 diff --git a/R/inlay_hint.R b/R/inlay_hint.R index 0390fff4..6c39f3a1 100644 --- a/R/inlay_hint.R +++ b/R/inlay_hint.R @@ -44,13 +44,13 @@ call_argument_groups <- function(call_node) { #' Whether a pipe supplies an implicit positional argument to this call #' @noRd call_has_implicit_argument <- function(call_node) { - operator <- xml_find_first(call_node, "preceding-sibling::*[not(self::COMMENT)][1]") + operator <- xml_find_first_(call_node, "preceding-sibling::*[not(self::COMMENT)][1]") if (inherits(operator, "xml_missing")) return(FALSE) if (xml_name(operator) %in% c("PIPE", "OP-PIPE")) { - return(xml_find_lgl(call_node, "not(expr[count(*) = 1]/PLACEHOLDER)")) + return(xml_find_lgl_(call_node, "not(expr[count(*) = 1]/PLACEHOLDER)")) } if (xml_name(operator) == "SPECIAL" && xml_text(operator) %in% c("%>%", "%<>%", "%T>%")) { - return(xml_find_lgl(call_node, "not(expr[count(*) = 1]/SYMBOL[text() = '.'])")) + return(xml_find_lgl_(call_node, "not(expr[count(*) = 1]/SYMBOL[text() = '.'])")) } FALSE } @@ -217,7 +217,7 @@ inlay_hint_reply <- function(id, uri, workspace, document, request_range) { if (request_range$end$character == 0L && end_line > start_line) { end_line <- end_line - 1L } - fn_nodes <- xml_find_all( + fn_nodes <- xml_find_all_( xdoc, paste0( "//SYMBOL_FUNCTION_CALL[parent::expr[", @@ -229,7 +229,7 @@ inlay_hint_reply <- function(id, uri, workspace, document, request_range) { if (!length(fn_nodes)) return(Response$new(id, result = list())) calls <- xml_parent(xml_parent(fn_nodes)) function_names <- xml_text(fn_nodes) - packages <- xml_find_chr(fn_nodes, "string(preceding-sibling::SYMBOL_PACKAGE[1])") + packages <- xml_find_chr_(fn_nodes, "string(preceding-sibling::SYMBOL_PACKAGE[1])") minimum_arguments <- lsp_settings$get("inlay_hints_minimum_arguments") if (!is.numeric(minimum_arguments) || length(minimum_arguments) != 1L || diff --git a/R/inline_value.R b/R/inline_value.R index 60d84d8b..dea79449 100644 --- a/R/inline_value.R +++ b/R/inline_value.R @@ -51,7 +51,7 @@ inline_value_reply <- function(id, uri, workspace, document, request_range) { end_line <- end_line - 1L } line_cond <- paste0("@line1 >= ", start_line, " and @line1 <= ", end_line) - nodes <- xml_find_all( + nodes <- xml_find_all_( xdoc, paste0("//SYMBOL[", line_cond, "] | //SYMBOL_FORMALS[", line_cond, "]") ) diff --git a/R/link.R b/R/link.R index 566cd96c..d5fc17bb 100644 --- a/R/link.R +++ b/R/link.R @@ -21,7 +21,7 @@ document_link_reply <- function(id, uri, workspace, document, rootPath) { # Limit string length to 255 to avoid potential PATH_MAX error on Windows # On macOS and Linux, PATH_MAX is much larger but we ignore the long strings at the moment. if (is.null(indexed)) { - str_tokens <- xml_find_all(xdoc, "//STR_CONST[@line1=@line2 and @col2>@col1+1 and @col2<=@col1+256]") + str_tokens <- xml_find_all_(xdoc, "//STR_CONST[@line1=@line2 and @col2>@col1+1 and @col2<=@col1+256]") indexed <- list( line = as.integer(xml_attr(str_tokens, "line1")), col1 = as.integer(xml_attr(str_tokens, "col1")), diff --git a/R/linked_editing.R b/R/linked_editing.R index f71b5961..1159d597 100644 --- a/R/linked_editing.R +++ b/R/linked_editing.R @@ -152,10 +152,10 @@ linked_editing_range_reply <- function(id, uri, workspace, document, point) { scopes <- xdoc_find_enclosing_scopes(xdoc, definition_row + 1L, definition$range$start$character + 1L) context <- if (length(scopes)) scopes[[1L]] else xdoc - function_nodes <- xml_find_all(context, xpath) + function_nodes <- xml_find_all_(context, xpath) if (!length(function_nodes)) next function_node <- function_nodes[[length(function_nodes)]] - formal_nodes <- xml_find_all(function_node, "SYMBOL_FORMALS") + formal_nodes <- xml_find_all_(function_node, "SYMBOL_FORMALS") if (!length(formal_nodes)) next } diff --git a/R/refactor.R b/R/refactor.R index 02e0950a..3e60a07b 100644 --- a/R/refactor.R +++ b/R/refactor.R @@ -133,7 +133,7 @@ refactor_sequence_container <- function(node) { name <- xml_name(node) identical(name, "exprlist") || identical(name, "expr") && - xml_find_lgl(node, "boolean(OP-LEFT-BRACE)") + xml_find_lgl_(node, "boolean(OP-LEFT-BRACE)") } #' Find the statement and sequential container enclosing an expression @@ -197,7 +197,7 @@ refactor_expression_movable <- function(node, statement) { } else { "boolean(.//PLACEHOLDER)" } - if (xml_find_lgl(node, placeholder)) return(FALSE) + if (xml_find_lgl_(node, placeholder)) return(FALSE) } assignments <- which(child_names %in% c( @@ -234,7 +234,7 @@ refactor_expression_movable <- function(node, statement) { #' Find an expression exactly matching a selected range #' @noRd refactor_exact_expression <- function(xdoc, selected_range) { - nodes <- xml_find_all(xdoc, "//expr[@line1]") + nodes <- xml_find_all_(xdoc, "//expr[@line1]") matches <- vapply(nodes, function(node) { refactor_range_equal(refactor_node_range(node), selected_range) }, logical(1L)) @@ -248,7 +248,7 @@ refactor_exact_expression <- function(xdoc, selected_range) { #' Find contiguous statement expressions matching a selected range #' @noRd refactor_statement_selection <- function(xdoc, selected_range) { - containers <- xml_find_all(xdoc, "/exprlist | //OP-LEFT-BRACE/parent::expr") + containers <- xml_find_all_(xdoc, "/exprlist | //OP-LEFT-BRACE/parent::expr") result <- NULL for (container in containers) { children <- xml_children(container) @@ -331,20 +331,20 @@ refactor_selection_context <- function(uri, workspace, document, item_range) { #' Return direct token names contained by a parse node #' @noRd refactor_token_names <- function(node) { - xml_name(xml_find_all(node, ".//*[not(*)]")) + xml_name(xml_find_all_(node, ".//*[not(*)]")) } #' Return function-call names contained by a parse node #' @noRd refactor_call_names <- function(node) { - xml_text(xml_find_all(node, ".//SYMBOL_FUNCTION_CALL")) + xml_text(xml_find_all_(node, ".//SYMBOL_FUNCTION_CALL")) } #' Detect syntax whose evaluation context cannot safely move #' @noRd refactor_unsafe_syntax <- function(node, extracting_function = FALSE) { token_names <- refactor_token_names(node) - token_text <- xml_text(xml_find_all( + token_text <- xml_text(xml_find_all_( node, ".//LEFT_ASSIGN | .//RIGHT_ASSIGN" )) @@ -516,7 +516,7 @@ refactor_multiline_quoted_ranges <- function(context) { ) })) } - quoted <- xml_find_all(context$xdoc, paste( + quoted <- xml_find_all_(context$xdoc, paste( "//STR_CONST[@line1 < @line2]", "//SYMBOL[@line1 < @line2]", "//SYMBOL_FUNCTION_CALL[@line1 < @line2]", @@ -614,7 +614,7 @@ refactor_insertion_context <- function(document, statement) { #' Test whether an expression is only a single atomic token #' @noRd refactor_atomic_expression <- function(node) { - terminals <- xml_find_all(node, ".//*[not(*)]") + terminals <- xml_find_all_(node, ".//*[not(*)]") length(terminals) == 1L && xml_name(terminals[[1L]]) %in% c( "SYMBOL", "NUM_CONST", "STR_CONST", "NULL_CONST" ) @@ -847,7 +847,7 @@ refactor_extract_function_action <- function(uri, workspace, document, return(NULL) } uses_dots <- vapply(selection$nodes, function(node) { - xml_find_lgl( + xml_find_lgl_( node, "boolean(.//SYMBOL[text() = '...'] | .//SYMBOL_FORMALS[text() = '...'])" ) diff --git a/R/references.R b/R/references.R index 503a419a..8540c513 100644 --- a/R/references.R +++ b/R/references.R @@ -334,7 +334,7 @@ references_reply <- function(id, uri, workspace, document, point, return(list()) } - symbols <- xml_find_all(xdoc, "//SYMBOL | //SYMBOL_FUNCTION_CALL | //SYMBOL_FORMALS") + symbols <- xml_find_all_(xdoc, "//SYMBOL | //SYMBOL_FUNCTION_CALL | //SYMBOL_FORMALS") symbols <- symbols[reference_symbol_names(xml_text(symbols)) == token$token] if (length(symbols) == 0) { return(list()) @@ -350,7 +350,7 @@ references_reply <- function(id, uri, workspace, document, point, for (i in seq_along(symbols)) { if (!isTRUE(include_declaration)) { is_declaration <- xml_name(symbols[[i]]) == "SYMBOL_FORMALS" || ( - xml_name(symbols[[i]]) == "SYMBOL" && xml_find_lgl(symbols[[i]], + xml_name(symbols[[i]]) == "SYMBOL" && xml_find_lgl_(symbols[[i]], "boolean(parent::forcond or parent::expr[count(*)=1 and (following-sibling::LEFT_ASSIGN or following-sibling::EQ_ASSIGN or preceding-sibling::RIGHT_ASSIGN)])") ) if (is_declaration) next diff --git a/R/section.R b/R/section.R index d0b0783c..ef51bac2 100644 --- a/R/section.R +++ b/R/section.R @@ -241,13 +241,13 @@ extract_document_block_lines <- function(xdoc) { if (is.null(xdoc)) { return(NULL) } - block_start <- xml_find_all(xdoc, "(//OP-LEFT-PAREN | //OP-LEFT-BRACKET | //OP-LEFT-BRACE)[parent::expr and + block_start <- xml_find_all_(xdoc, "(//OP-LEFT-PAREN | //OP-LEFT-BRACKET | //OP-LEFT-BRACE)[parent::expr and @line1 < (following-sibling::OP-RIGHT-PAREN | following-sibling::OP-RIGHT-BRACKET | following-sibling::OP-RIGHT-BRACE)/@line1]") if (!length(block_start)) { # prevent floating point comparision return(NULL) } - block_end <- xml_find_first(block_start, "following-sibling::OP-RIGHT-PAREN | following-sibling::OP-RIGHT-BRACKET | following-sibling::OP-RIGHT-BRACE") + block_end <- xml_find_first_(block_start, "following-sibling::OP-RIGHT-PAREN | following-sibling::OP-RIGHT-BRACKET | following-sibling::OP-RIGHT-BRACE") block_start_line <- as.integer(xml_attr(block_start, "line1")) block_end_line <- as.integer(xml_attr(block_end, "line1")) diff --git a/R/selection.R b/R/selection.R index 146d18e5..a5faf270 100644 --- a/R/selection.R +++ b/R/selection.R @@ -37,7 +37,7 @@ selection_range_reply <- function(id, uri, workspace, document, points) { row <- point$row + 1 col <- point$col + 1 token <- xdoc_find_token(xdoc, row, col) - nodes <- xml_find_all(token, "ancestor-or-self::*[@line1]") + nodes <- xml_find_all_(token, "ancestor-or-self::*[@line1]") ranges <- lapply(nodes, function(token) { range( start = document$to_lsp_position( diff --git a/R/semantic.R b/R/semantic.R index c20cacc0..817212b2 100644 --- a/R/semantic.R +++ b/R/semantic.R @@ -175,39 +175,39 @@ xml_superassign_target_expr_xpath <- " #' Resolve the nearest lexical binding kind ("formal", "local", or "none") for an XML SYMBOL #' @noRd xml_symbol_binding_kind <- function(token_node, sym_name) { - if (xml_find_lgl(token_node, paste0("boolean(", xml_superassign_target_expr_xpath, ")"))) { - target_expr <- xml_find_first(token_node, xml_superassign_target_expr_xpath) - first_sym <- xml_find_first( + if (xml_find_lgl_(token_node, paste0("boolean(", xml_superassign_target_expr_xpath, ")"))) { + target_expr <- xml_find_first_(token_node, xml_superassign_target_expr_xpath) + first_sym <- xml_find_first_( target_expr, paste0("descendant::SYMBOL[", xml_not_qualified_symbol_xpath, "][1]") ) if (identical(first_sym, token_node)) { - if (xml_find_lgl(target_expr, "not(ancestor::expr[FUNCTION or OP-LAMBDA])")) { + if (xml_find_lgl_(target_expr, "not(ancestor::expr[FUNCTION or OP-LAMBDA])")) { return("none") } - token_node <- xml_find_first(target_expr, "ancestor::expr[FUNCTION or OP-LAMBDA][1]") + token_node <- xml_find_first_(target_expr, "ancestor::expr[FUNCTION or OP-LAMBDA][1]") } } ancestor_formals <- setdiff( reference_symbol_names( - xml_text(xml_find_all(token_node, "ancestor::expr/SYMBOL_FORMALS")) + xml_text(xml_find_all_(token_node, "ancestor::expr/SYMBOL_FORMALS")) ), "..." ) if (!(sym_name %in% ancestor_formals)) { return("none") } - if (xml_find_lgl( + if (xml_find_lgl_( token_node, "not(ancestor::expr[FUNCTION or OP-LAMBDA][2] or ancestor::expr/forcond)" )) { return("formal") } - scopes <- xml_find_all( + scopes <- xml_find_all_( token_node, "ancestor::expr[FUNCTION or OP-LAMBDA or forcond]" ) - loop_syms <- xml_find_chr(scopes, "string(forcond/SYMBOL)") + loop_syms <- xml_find_chr_(scopes, "string(forcond/SYMBOL)") is_for <- nzchar(loop_syms) fn_depths <- cumsum(!is_for) for (i in rev(seq_along(scopes))) { @@ -220,13 +220,13 @@ xml_symbol_binding_kind <- function(token_node, sym_name) { scope_node <- scopes[[i]] formal_names <- setdiff( reference_symbol_names( - xml_text(xml_find_all(scope_node, "SYMBOL_FORMALS")) + xml_text(xml_find_all_(scope_node, "SYMBOL_FORMALS")) ), "..." ) if (sym_name %in% formal_names) return("formal") - local_nodes <- xml_find_all(scope_node, xml_scope_local_symbols_xpath) + local_nodes <- xml_find_all_(scope_node, xml_scope_local_symbols_xpath) if (length(local_nodes)) { local_names <- reference_symbol_names(xml_text(local_nodes)) matching_nodes <- local_nodes[local_names == sym_name] @@ -235,7 +235,7 @@ xml_symbol_binding_kind <- function(token_node, sym_name) { "not(ancestor::expr[FUNCTION or OP-LAMBDA][%d])", fn_depths[[i]] + 1L ) - if (any(xml_find_lgl(matching_nodes, not_nested_xpath))) { + if (any(xml_find_lgl_(matching_nodes, not_nested_xpath))) { return("local") } } @@ -455,15 +455,15 @@ xml_function_assignment_rhs_xpath <- " #' Whether an XML SYMBOL is assigned `function()` or `\()` #' @noRd xml_symbol_is_function_assignment <- function(node) { - if (xml_find_lgl(node, paste0("not(", xml_function_assignment_rhs_xpath, ")"))) { + if (xml_find_lgl_(node, paste0("not(", xml_function_assignment_rhs_xpath, ")"))) { return(FALSE) } - rhs <- xml_find_first(node, xml_function_assignment_rhs_xpath) + rhs <- xml_find_first_(node, xml_function_assignment_rhs_xpath) repeat { - if (xml_find_lgl(rhs, "boolean(FUNCTION or OP-LAMBDA)")) { + if (xml_find_lgl_(rhs, "boolean(FUNCTION or OP-LAMBDA)")) { return(TRUE) } - children <- xml_find_all(rhs, "*[not(self::COMMENT)]") + children <- xml_find_all_(rhs, "*[not(self::COMMENT)]") if (length(children) != 3L) { return(FALSE) } @@ -833,7 +833,7 @@ extract_semantic_tokens <- function(uri, workspace, document, range = NULL) { } # Get all token elements from the parse tree - token_elements <- xml_find_all(xdoc, semantic_tokens_xpath) + token_elements <- xml_find_all_(xdoc, semantic_tokens_xpath) if (length(token_elements) == 0) { return(list()) @@ -894,7 +894,7 @@ extract_semantic_tokens <- function(uri, workspace, document, range = NULL) { if (xml_symbol_is_function_assignment(token_node)) { token_type <- SemanticTokenTypes[["function"]] modifiers <- semantic_declaration_modifier - } else if (xml_find_lgl(token_node, xml_not_qualified_symbol_xpath)) { + } else if (xml_find_lgl_(token_node, xml_not_qualified_symbol_xpath)) { if (is_semantic_ellipsis_symbol(tok_text)) { token_type <- SemanticTokenTypes$variable modifiers <- semantic_readonly_default_modifier @@ -906,7 +906,7 @@ extract_semantic_tokens <- function(uri, workspace, document, range = NULL) { } } } else if (token_name == "SYMBOL_FUNCTION_CALL") { - if (identical(tok_text, "return") && xml_find_lgl(token_node, xml_not_qualified_symbol_xpath)) { + if (identical(tok_text, "return") && xml_find_lgl_(token_node, xml_not_qualified_symbol_xpath)) { token_type <- SemanticTokenTypes$keyword } } else if (token_name == "SYMBOL_FORMALS") { diff --git a/R/signature.R b/R/signature.R index e2a32cb3..3f2db8be 100644 --- a/R/signature.R +++ b/R/signature.R @@ -3,7 +3,7 @@ signature_xpath <- "(* | descendant-or-self::expr | descendant-or-self::expr_or_ #' Format local function arguments without reparsing the function body #' @noRd local_function_signature <- function(document, node, symbol) { - closing <- xml_find_first(node, "OP-RIGHT-PAREN") + closing <- xml_find_first_(node, "OP-RIGHT-PAREN") text <- get_range_text(document$content, line1 = as.integer(xml_attr(node, "line1")), col1 = as.integer(xml_attr(node, "col1")), diff --git a/R/type_hierarchy.R b/R/type_hierarchy.R index 7825f986..dea36c50 100644 --- a/R/type_hierarchy.R +++ b/R/type_hierarchy.R @@ -976,7 +976,7 @@ extract_r6_list_members <- function(document, list_node, access_modifier) { } # Check if this specific value expression contains a FUNCTION keyword - is_function <- xml_find_lgl(value_expr, "boolean(.//FUNCTION)") + is_function <- xml_find_lgl_(value_expr, "boolean(.//FUNCTION)") member_kind <- if (is_function) SymbolKind$Method else SymbolKind$Field member_range <- get_element_range(document, symbol_sub) diff --git a/R/utils.R b/R/utils.R index 5d0013f4..e000976e 100644 --- a/R/utils.R +++ b/R/utils.R @@ -692,7 +692,7 @@ xdoc_top_level_index <- function(x, syntax = NULL, navigation = NULL) { # XML is needed by legacy providers, but syntax facts are already # built in the worker. Map preorder rows once instead of rediscovering # token attributes and assignment predicates on the main thread. - all_nodes <- xml_find_all(x, "descendant::*") + all_nodes <- xml_find_all_(x, "descendant::*") if (length(all_nodes) == length(syntax$id)) { rank <- syntax$order_rank roots <- syntax$roots[syntax$token[syntax$roots] == "expr"] @@ -714,7 +714,7 @@ xdoc_top_level_index <- function(x, syntax = NULL, navigation = NULL) { nodes <- nodes[xml_name(nodes) == "expr"] # An explicit descendant axis avoids libxml2 repeatedly merging terminal # node sets for //*, which becomes quadratic in long, flat scripts. - tokens <- xml_find_all(x, "descendant-or-self::*[@line1 and not(*)]") + tokens <- xml_find_all_(x, "descendant-or-self::*[@line1 and not(*)]") token_line1 <- as.integer(xml_attr(tokens, "line1")) token_col1 <- as.integer(xml_attr(tokens, "col1")) token_line2 <- as.integer(xml_attr(tokens, "line2")) @@ -727,7 +727,7 @@ xdoc_top_level_index <- function(x, syntax = NULL, navigation = NULL) { all(token_line2[previous] < token_line1[following] | token_line2[previous] == token_line1[following] & token_col2[previous] < token_col1[following]) - definition_symbols <- xml_find_all(x, paste( + definition_symbols <- xml_find_all_(x, paste( "(//LEFT_ASSIGN | //EQ_ASSIGN)/preceding-sibling::expr[count(*)=1]/SYMBOL", "//RIGHT_ASSIGN/following-sibling::expr[count(*)=1]/SYMBOL", sep = " | " @@ -762,7 +762,7 @@ xdoc_find_enclosing_scopes <- function(x, line, col, top = FALSE) { rows <- .Call("syntax_enclosing_c", index$syntax, as.integer(c(line, col)), PACKAGE = "languageserver") scopes <- index$all_nodes[index$syntax$order_rank[rows]] if (top) { - root <- xml_find_all(x, "/exprlist") + root <- xml_find_all_(x, "/exprlist") return(structure(c(unclass(root), unclass(scopes)), class = "xml_nodeset")) } return(scopes) @@ -778,19 +778,19 @@ xdoc_find_enclosing_scopes <- function(x, line, col, top = FALSE) { "/exprlist/expr[", condition, "]/descendant-or-self::expr[", condition, "]" ) - scopes <- xml_find_all(x, xpath) + scopes <- xml_find_all_(x, xpath) } else { selected <- (index$line1 < line | index$line1 == line & index$col1 <= col) & (index$line2 > line | index$line2 == line & index$col2 >= col - 1L) - scopes <- xml_find_all(index$nodes[selected], + scopes <- xml_find_all_(index$nodes[selected], paste0("descendant-or-self::expr[", condition, "]")) } if (top) { - root <- xml_find_all(x, "/exprlist") + root <- xml_find_all_(x, "/exprlist") structure(c(unclass(root), unclass(scopes)), class = "xml_nodeset") } else { scopes @@ -816,7 +816,7 @@ xdoc_find_definitions <- function(x, line, col, name, xpath) { } if (is.null(index$definitions_by_name)) { scopes <- xdoc_find_enclosing_scopes(x, line, col, top = TRUE) - return(xml_find_all(scopes, xpath)) + return(xml_find_all_(scopes, xpath)) } selected <- get0(name, envir = index$definitions_by_name, inherits = FALSE, ifnotfound = integer()) @@ -834,7 +834,7 @@ xdoc_find_definitions <- function(x, line, col, name, xpath) { "(* | self::expr | self::expr_or_assign_or_help)", xpath, fixed = TRUE ) - xml_find_all(contexts, shallow_xpath) + xml_find_all_(contexts, shallow_xpath) } xdoc_find_token <- function(x, line, col) { @@ -846,13 +846,13 @@ xdoc_find_token <- function(x, line, col) { index$is_string, as.integer(c(line, col)) ) if (selected > 0L) return(index$nodes[[selected]]) - return(xml_find_first(x, "/*[false()]")) + return(xml_find_first_(x, "/*[false()]")) } xpath <- glue("//*[not(*)][(@line1 < {line} or (@line1 = {line} and @col1 <= {col})) and (@line2 > {line} or (@line2 = {line} and @col2 >= {col}-1))]", line = line, col = col) - tokens <- xml_find_all(x, xpath) + tokens <- xml_find_all_(x, xpath) if (!length(tokens)) { - return(xml_find_first(x, "/*[false()]")) + return(xml_find_first_(x, "/*[false()]")) } # A cursor at the boundary before a string literal can match both the @@ -930,3 +930,33 @@ range_overlap <- function(range1, range2) { compare_position(range2$end, range1$start) < 0 || compare_position(range2$start, range1$end) > 0) } + +# TODO(r-lib/xml2#327): Remove this workaround if upstream bottleneck is resolved. +# placeholder xml_ns() object to skip this call on xml2 invocations +empty_ns <- character() +names(empty_ns) <- character() +class(empty_ns) <- "xml_namespace" + +xml_find_all_ <- function(x, xpath, ns = empty_ns, ...) { + xml_find_all(x, xpath, ns = ns, ...) +} + +xml_find_first_ <- function(x, xpath, ns = empty_ns) { + xml_find_first(x, xpath, ns = ns) +} + +xml_find_chr_ <- function(x, xpath, ns = empty_ns) { + xml_find_chr(x, xpath, ns = ns) +} + +xml_find_num_ <- function(x, xpath, ns = empty_ns) { + xml_find_num(x, xpath, ns = ns) +} + +xml_find_lgl_ <- function(x, xpath, ns = empty_ns) { + xml_find_lgl(x, xpath, ns = ns) +} + +xml_child_ <- function(x, search = 1L, ns = empty_ns) { + xml_child(x, search = search, ns = ns) +}