@@ -82,8 +82,8 @@ indentation_linter <- function(indent = 2L, use_hybrid_indent = TRUE) {
82
82
paste(
83
83
c(
84
84
glue :: glue(" self::{paren_tokens_left}/following-sibling::{paren_tokens_right}/preceding-sibling::*[1]/@line2" ),
85
- glue :: glue(" self::*[{xp_and(paste0('not(self::', paren_tokens_left, ')'))}]/following-sibling::SYMBOL_FUNCTION_CALL/
86
- parent::expr/following-sibling::expr[1]/@line2" ),
85
+ glue :: glue(" self::*[{xp_and(paste0('not(self::', paren_tokens_left, ')'))}]
86
+ /following-sibling::SYMBOL_FUNCTION_CALL/ parent::expr/following-sibling::expr[1]/@line2" ),
87
87
glue :: glue(" self::*[
88
88
{xp_and(paste0('not(self::', paren_tokens_left, ')'))} and
89
89
not(following-sibling::SYMBOL_FUNCTION_CALL)
@@ -113,19 +113,25 @@ indentation_linter <- function(indent = 2L, use_hybrid_indent = TRUE) {
113
113
xp_multiline_string <- " //STR_CONST[@line1 < @line2]"
114
114
115
115
Linter(function (source_expression ) {
116
- if (! is_lint_level(source_expression , " expression" )) {
116
+ # must run on file level because a line can contain multiple expressions, losing indentation information, e.g.
117
+ #
118
+ # > fun(
119
+ # a) # comment
120
+ #
121
+ # will have "# comment" as a separate expression
122
+ if (! is_lint_level(source_expression , " file" )) {
117
123
return (list ())
118
124
}
119
125
120
- xml <- source_expression $ xml_parsed_content
126
+ xml <- source_expression $ full_xml_parsed_content
121
127
# Indentation increases by 1 for:
122
128
# - { } blocks that span multiple lines
123
129
# - ( ), [ ], or [[ ]] calls that span multiple lines
124
130
# + if a token follows (, a hanging indent is required until )
125
131
# + if there is no token following ( on the same line, a block indent is required until )
126
132
# - binary operators where the second arguments starts on a new line
127
133
128
- indent_levels <- rex :: re_matches(source_expression $ lines , rex :: rex(start , any_spaces ), locations = TRUE )[, " end" ]
134
+ indent_levels <- rex :: re_matches(source_expression $ file_lines , rex :: rex(start , any_spaces ), locations = TRUE )[, " end" ]
129
135
expected_indent_levels <- integer(length(indent_levels ))
130
136
is_hanging <- logical (length(indent_levels ))
131
137
@@ -135,7 +141,7 @@ indentation_linter <- function(indent = 2L, use_hybrid_indent = TRUE) {
135
141
change_begin <- as.integer(xml2 :: xml_attr(change , " line1" )) + 1L
136
142
change_end <- xml2 :: xml_find_num(change , xp_block_ends )
137
143
if (change_begin < = change_end ) {
138
- to_indent <- seq(from = change_begin , to = change_end ) - source_expression $ line + 1L
144
+ to_indent <- seq(from = change_begin , to = change_end )
139
145
if (change_starts_hanging ) {
140
146
expected_indent_levels [to_indent ] <- as.integer(xml2 :: xml_attr(change , " col2" ))
141
147
is_hanging [to_indent ] <- TRUE
@@ -152,12 +158,12 @@ indentation_linter <- function(indent = 2L, use_hybrid_indent = TRUE) {
152
158
is_in_str <- seq(
153
159
from = as.integer(xml2 :: xml_attr(string , " line1" )) + 1L ,
154
160
to = as.integer(xml2 :: xml_attr(string , " line2" ))
155
- ) - source_expression $ line + 1L
161
+ )
156
162
in_str_const [is_in_str ] <- TRUE
157
163
}
158
164
159
165
# Only lint non-empty lines if the indentation level doesn't match.
160
- bad_lines <- which(indent_levels != expected_indent_levels & nzchar(source_expression $ lines ) & ! in_str_const )
166
+ bad_lines <- which(indent_levels != expected_indent_levels & nzchar(trimws( source_expression $ file_lines ) ) & ! in_str_const )
161
167
if (length(bad_lines )) {
162
168
# Suppress consecutive lints with the same indentation difference, to not generate an excessive number of lints
163
169
is_consecutive_lint <- c(FALSE , diff(bad_lines ) == 1L )
@@ -172,7 +178,7 @@ indentation_linter <- function(indent = 2L, use_hybrid_indent = TRUE) {
172
178
expected_indent_levels [bad_lines ],
173
179
indent_levels [bad_lines ]
174
180
)
175
- lint_lines <- unname(as.integer(names(source_expression $ lines )[bad_lines ]))
181
+ lint_lines <- unname(as.integer(names(source_expression $ file_lines )[bad_lines ]))
176
182
lint_ranges <- cbind(
177
183
pmin(expected_indent_levels [bad_lines ] + 1L , indent_levels [bad_lines ]),
178
184
pmax(expected_indent_levels [bad_lines ], indent_levels [bad_lines ])
@@ -184,7 +190,7 @@ indentation_linter <- function(indent = 2L, use_hybrid_indent = TRUE) {
184
190
column_number = indent_levels [bad_lines ],
185
191
type = " style" ,
186
192
message = lint_messages ,
187
- line = unname(source_expression $ lines [bad_lines ]),
193
+ line = unname(source_expression $ file_lines [bad_lines ]),
188
194
ranges = apply(lint_ranges , 1L , list , simplify = FALSE )
189
195
)
190
196
} else {
0 commit comments