-
Notifications
You must be signed in to change notification settings - Fork 195
Unified brace_linter #1092
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unified brace_linter #1092
Changes from 8 commits
e9808c5
b7e3460
4ec4348
ee38e40
cdfbfd7
a251c1e
733c4e1
1e42069
b1f1dd8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| #' Brace linter | ||
| #' | ||
| #' Perform various style checks related to placement and spacing of curly braces: | ||
| #' | ||
| #' - Curly braces are on their own line unless they are followed by an `else`. | ||
| #' | ||
| #' @param allow_single_line if `TRUE`, allow an open and closed curly pair on the same line. | ||
| #' | ||
| #' @evalRd rd_tags("brace_linter") | ||
| #' @seealso [linters] for a complete list of linters available in lintr. | ||
| #' @export | ||
| brace_linter <- function(allow_single_line = FALSE) { | ||
| Linter(function(source_expression) { | ||
| if (length(source_expression$xml_parsed_content) == 0L) { | ||
| return(list()) | ||
| } | ||
|
|
||
| lints <- list() | ||
|
|
||
| xp_cond_closed <- xp_and(c( | ||
| # matching { is on same line | ||
| if (isTRUE(allow_single_line)) { | ||
| "(@line1 != preceding-sibling::OP-LEFT-BRACE/@line1)" | ||
| }, | ||
| # immediately followed by ",", "]" or ")" | ||
| "not( | ||
| @line1 = ancestor::expr/following-sibling::*[1][ | ||
| self::OP-COMMA or self::OP-RIGHT-BRACKET or self::OP-RIGHT-PAREN | ||
| ]/@line1 | ||
| )", | ||
| # double curly | ||
| "not( | ||
| (@line1 = parent::expr/following-sibling::OP-RIGHT-BRACE/@line1) or | ||
| (@line1 = preceding-sibling::expr/OP-RIGHT-BRACE/@line1) | ||
| )" | ||
| )) | ||
|
|
||
| xp_closed_curly <- glue::glue("//OP-RIGHT-BRACE[ | ||
| { xp_cond_closed } and ( | ||
| (@line1 = preceding-sibling::*[1]/@line2) or | ||
| (@line1 = parent::expr/following-sibling::*[1][not(self::ELSE)]/@line1) | ||
| ) | ||
| ]") | ||
|
|
||
| lints <- c(lints, lapply( | ||
| xml2::xml_find_all(source_expression$xml_parsed_content, xp_closed_curly), | ||
| xml_nodes_to_lint, | ||
| source_file = source_expression, | ||
| lint_message = paste( | ||
| "Closing curly-braces should always be on their own line,", | ||
| "unless they are followed by an else." | ||
| ) | ||
| )) | ||
|
|
||
| lints | ||
| }) | ||
| } | ||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| test_that("brace_linter lints closed braces correctly", { | ||
| closed_curly_msg <- rex::rex(paste( | ||
| "Closing curly-braces should always be on their own line,", | ||
| "unless they are followed by an else." | ||
| )) | ||
|
|
||
| linter <- brace_linter() | ||
| expect_lint("blah", NULL, linter) | ||
| expect_lint("a <- function() {\n}", NULL, linter) | ||
|
|
||
| expect_lint("a <- function() { 1 }", closed_curly_msg, linter) | ||
| # allowed by allow_single_line | ||
| expect_lint("a <- function() { 1 }", NULL, brace_linter(allow_single_line = TRUE)) | ||
|
|
||
| expect_lint( | ||
| trim_some(" | ||
| a <- if(1) { | ||
| 1} else { | ||
| 2 | ||
| } | ||
| "), | ||
| closed_curly_msg, | ||
| linter | ||
| ) | ||
| expect_lint( | ||
| trim_some(" | ||
| a <- if(1) { | ||
| 1 | ||
| } else { | ||
| 2} | ||
| "), | ||
| closed_curly_msg, | ||
| linter | ||
| ) | ||
|
|
||
| expect_lint( | ||
| trim_some(" | ||
| a <- if(1) { | ||
| 1} else { | ||
| 2} | ||
| "), | ||
| list( | ||
| closed_curly_msg, | ||
| closed_curly_msg | ||
| ), | ||
| linter | ||
| ) | ||
|
|
||
| # }) is allowed | ||
| expect_lint("eval(bquote({...}))", NULL, linter) | ||
MichaelChirico marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| # }] is too | ||
| expect_lint("df[, {...}]", NULL, linter) | ||
|
|
||
| # }, is allowed | ||
AshesITR marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| expect_lint( | ||
| trim_some(" | ||
| fun({ | ||
| statements | ||
| }, param)"), | ||
| NULL, | ||
| linter | ||
| ) | ||
| expect_lint( | ||
| trim_some(" | ||
| fun(function(a) { | ||
| statements | ||
| }, param)"), | ||
| NULL, | ||
| linter | ||
| ) | ||
|
|
||
| expect_lint( | ||
| trim_some(" | ||
| out <- lapply(stuff, function(i) { | ||
| do_something(i) | ||
| }) %>% unlist | ||
| "), | ||
| NULL, | ||
| linter | ||
| ) | ||
|
|
||
| # }} is allowed | ||
| expect_lint("{{ x }}", NULL, linter) | ||
| }) | ||
Uh oh!
There was an error while loading. Please reload this page.