Nothing
#' Semicolon linter
#'
#' Check that no semicolons terminate expressions.
#'
#' @param allow_compound Logical, default `FALSE`. If `TRUE`, "compound"
#' semicolons (e.g. as in `x; y`, i.e., on the same line of code) are allowed.
#' @param allow_trailing Logical, default `FALSE`. If `TRUE`, "trailing"
#' semicolons (i.e., those that terminate lines of code) are allowed.
#'
#' @examples
#' # will produce lints
#' lint(
#' text = "a <- 1;",
#' linters = semicolon_linter()
#' )
#'
#' lint(
#' text = "a <- 1; b <- 1",
#' linters = semicolon_linter()
#' )
#'
#' lint(
#' text = "function() { a <- 1; b <- 1 }",
#' linters = semicolon_linter()
#' )
#'
#' # okay
#' lint(
#' text = "a <- 1",
#' linters = semicolon_linter()
#' )
#'
#' lint(
#' text = "a <- 1;",
#' linters = semicolon_linter(allow_trailing = TRUE)
#' )
#'
#' code_lines <- "a <- 1\nb <- 1"
#' writeLines(code_lines)
#' lint(
#' text = code_lines,
#' linters = semicolon_linter()
#' )
#'
#' lint(
#' text = "a <- 1; b <- 1",
#' linters = semicolon_linter(allow_compound = TRUE)
#' )
#'
#' code_lines <- "function() { \n a <- 1\n b <- 1\n}"
#' writeLines(code_lines)
#' lint(
#' text = code_lines,
#' linters = semicolon_linter()
#' )
#'
#' @evalRd rd_tags("semicolon_linter")
#' @seealso
#' - [linters] for a complete list of linters available in lintr.
#' - <https://style.tidyverse.org/syntax.html#semicolons>
#' @export
semicolon_linter <- function(allow_compound = FALSE, allow_trailing = FALSE) {
msg_trailing <- "Trailing semicolons are not needed."
msg_compound <- "Compound semicolons are discouraged. Replace them by a newline."
if (allow_compound && allow_trailing) {
stop("At least one of `allow_compound` or `allow_trailing` must be FALSE, otherwise no lints can be generated.")
} else if (allow_compound && !allow_trailing) {
# lint only trailing
xpath <- "//OP-SEMICOLON[not(@line1 = following-sibling::*[1]/@line1)]"
msg <- msg_trailing # nolint: object_usage. (usage in linter, since need_detection == FALSE)
need_detection <- FALSE
} else if (!allow_compound && allow_trailing) {
# lint only compound
xpath <- "//OP-SEMICOLON[@line1 = following-sibling::*[1]/@line1]"
msg <- msg_compound # nolint: object_usage. (usage in linter, since need_detection == FALSE)
need_detection <- FALSE
} else {
# lint all
xpath <- "//OP-SEMICOLON"
need_detection <- TRUE
}
compound_xpath <- "self::*[@line1 = following-sibling::*[1]/@line1]"
Linter(function(source_expression) {
if (!is_lint_level(source_expression, "file")) {
return(list())
}
xml <- source_expression$full_xml_parsed_content
bad_exprs <- xml_find_all(xml, xpath)
if (need_detection) {
is_trailing <- is.na(xml_find_first(bad_exprs, compound_xpath))
msg <- ifelse(is_trailing, msg_trailing, msg_compound)
}
xml_nodes_to_lints(
bad_exprs,
source_expression = source_expression,
lint_message = msg
)
})
}
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.