Skip to content

Commit 63f6fe0

Browse files
Comment on preceding line fine with brace_linter() (#1451)
* Comment on preceding line fine w/ `brace_linter()` Closes #1433 Closes #1434 * Update NEWS.md * add comment about native pipe * remove lints * add a failing test for regression * start with suggested * any prior line, not just exactly one prior * tweak NEWS Co-authored-by: Michael Chirico <michaelchirico4@gmail.com>
1 parent 8794907 commit 63f6fe0

File tree

3 files changed

+63
-10
lines changed

3 files changed

+63
-10
lines changed

NEWS.md

+3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66

77
## Changes to defaults
88

9+
* `brace_linter()` allows opening curly braces on a new line when there is
10+
a comment ending the preceding line (#1433 and #1434, @IndrajeetPatil).
11+
912
* `seq_linter()` produces lint for `seq(...)`, since it also cannot properly
1013
handle empty edge cases (#1468, @IndrajeetPatil).
1114

R/brace_linter.R

+15-9
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,15 @@ brace_linter <- function(allow_single_line = FALSE) {
2929
(@line1 = following-sibling::expr/OP-LEFT-BRACE/@line1)
3030
)",
3131
# allow `(`, `,` and `%>%` on preceding line
32+
#
33+
# note that '{' is not supported in RHS call of base-R's native pipe (`|>`),
34+
# so no exception needs to be made for this operator
3235
"not(
33-
@line1 = parent::expr/preceding-sibling::*[1][
34-
self::OP-LEFT-PAREN or self::OP-COMMA or (self::SPECIAL and text() = '%>%')
35-
]/@line2 + 1
36+
@line1 > parent::expr/preceding-sibling::*[not(self::COMMENT)][1][
37+
self::OP-LEFT-PAREN or
38+
self::OP-COMMA or
39+
(self::SPECIAL and text() = '%>%')
40+
]/@line2
3641
)"
3742
))
3843

@@ -110,41 +115,42 @@ brace_linter <- function(allow_single_line = FALSE) {
110115
return(list())
111116
}
112117

118+
xml <- source_expression$xml_parsed_content
113119
lints <- list()
114120

115121
lints <- c(lints, xml_nodes_to_lints(
116-
xml2::xml_find_all(source_expression$xml_parsed_content, xp_open_curly),
122+
xml2::xml_find_all(xml, xp_open_curly),
117123
source_expression = source_expression,
118124
lint_message =
119125
"Opening curly braces should never go on their own line and should always be followed by a new line."
120126
))
121127

122128
lints <- c(lints, xml_nodes_to_lints(
123-
xml2::xml_find_all(source_expression$xml_parsed_content, xp_paren_brace),
129+
xml2::xml_find_all(xml, xp_paren_brace),
124130
source_expression = source_expression,
125131
lint_message = "There should be a space before an opening curly brace."
126132
))
127133

128134
lints <- c(lints, xml_nodes_to_lints(
129-
xml2::xml_find_all(source_expression$xml_parsed_content, xp_closed_curly),
135+
xml2::xml_find_all(xml, xp_closed_curly),
130136
source_expression = source_expression,
131137
lint_message = "Closing curly-braces should always be on their own line, unless they are followed by an else."
132138
))
133139

134140
lints <- c(lints, xml_nodes_to_lints(
135-
xml2::xml_find_all(source_expression$xml_parsed_content, xp_else_same_line),
141+
xml2::xml_find_all(xml, xp_else_same_line),
136142
source_expression = source_expression,
137143
lint_message = "`else` should come on the same line as the previous `}`."
138144
))
139145

140146
lints <- c(lints, xml_nodes_to_lints(
141-
xml2::xml_find_all(source_expression$xml_parsed_content, xp_function_brace),
147+
xml2::xml_find_all(xml, xp_function_brace),
142148
source_expression = source_expression,
143149
lint_message = "Any function spanning multiple lines should use curly braces."
144150
))
145151

146152
lints <- c(lints, xml_nodes_to_lints(
147-
xml2::xml_find_all(source_expression$xml_parsed_content, xp_if_else_match_brace),
153+
xml2::xml_find_all(xml, xp_if_else_match_brace),
148154
source_expression = source_expression,
149155
lint_message = "Either both or neither branch in `if`/`else` should use curly braces."
150156
))

tests/testthat/test-brace_linter.R

+45-1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,40 @@ test_that("brace_linter lints braces correctly", {
100100
linter
101101
)
102102

103+
# a comment before ,<\n>{ is allowed
104+
expect_lint(
105+
trim_some("
106+
switch(
107+
x,
108+
'a' = do_something(x),
109+
'b' = do_another(x), # comment
110+
{
111+
do_first(x)
112+
do_second(x)
113+
}
114+
)
115+
"),
116+
NULL,
117+
linter
118+
)
119+
120+
# a comment before <\n>{ is allowed
121+
expect_lint(
122+
trim_some("
123+
switch(stat,
124+
o = {
125+
x <- 0.01
126+
},
127+
# else
128+
{
129+
x <- 2
130+
}
131+
)
132+
"),
133+
NULL,
134+
linter
135+
)
136+
103137
expect_lint(
104138
trim_some("
105139
fun(
@@ -162,6 +196,16 @@ test_that("brace_linter lints braces correctly", {
162196
linter
163197
)
164198

199+
expect_lint(
200+
"a <- function()
201+
# comment
202+
{
203+
1
204+
}",
205+
open_curly_msg,
206+
linter
207+
)
208+
165209
expect_lint("a <- function()\n{\n 1 \n}", open_curly_msg, linter)
166210
expect_lint("a <- function()\n {\n 1 \n}", open_curly_msg, linter)
167211
expect_lint("a <- function()\n\t{\n 1 \n}", open_curly_msg, linter)
@@ -233,7 +277,7 @@ test_that("brace_linter lints spaces before open braces", {
233277
list(
234278
rex::rex("Opening curly braces should never go on their own line and should always be followed by a new line."),
235279
rex::rex("Closing curly-braces should always be on their own line, unless they are followed by an else.")
236-
), #, but not msg
280+
), # , but not msg
237281
linter
238282
)
239283
})

0 commit comments

Comments
 (0)