@@ -45,34 +45,51 @@ object_usage_linter <- function() {
4545 }
4646 res <- parse_check_usage(fun )
4747
48- lapply(which(! is.na(res $ message )),
49- function (row_num ) {
50- row <- res [row_num , ]
51-
52- if (row $ name %in% declared_globals ) {
53- return ()
54- }
55-
56- org_line_num <- as.integer(row $ line_number ) + info $ line1 - 1L
57-
58- line <- source_file $ content [as.integer(org_line_num )]
59-
60- row $ name <- re_substitutes(row $ name , rex(" <-" ), " " )
61-
62- location <- re_matches(line ,
63- rex(row $ name ),
64- locations = TRUE )
65-
66- Lint(
67- filename = source_file $ filename ,
68- line_number = org_line_num ,
69- column_number = location $ start ,
70- type = " warning" ,
71- message = row $ message ,
72- line = line ,
73- ranges = list (c(location $ start , location $ end ))
74- )
75- })
48+ lapply(
49+ which(! is.na(res $ message )),
50+ function (row_num ) {
51+ row <- res [row_num , ]
52+
53+ if (row $ name %in% declared_globals ) {
54+ return ()
55+ }
56+
57+ org_line_num <- as.integer(row $ line1 ) + info $ line1 - 1L
58+ line <- source_file $ content [as.integer(org_line_num )]
59+
60+ row $ name <- re_substitutes(row $ name , rex(" <-" ), " " )
61+
62+ location <- re_matches(line , rex(boundary , row $ name , boundary ), locations = TRUE )
63+
64+ # Handle multi-line lints where name occurs on subsequent lines (#507)
65+ if (is.na(location $ start ) && nzchar(row $ line2 ) && row $ line2 != row $ line1 ) {
66+ lines <- source_file $ content [org_line_num : (as.integer(row $ line2 ) + info $ line1 - 1L )]
67+ locations <- re_matches(lines , rex(boundary , row $ name , boundary ), locations = TRUE )
68+
69+ matching_row <- (which(! is.na(locations $ start )) %|| % 1L )[[1L ]] # first matching row or 1 (as a fallback)
70+
71+ org_line_num <- org_line_num + matching_row - 1L
72+ location <- locations [matching_row , ]
73+ line <- lines [matching_row ]
74+ }
75+
76+ # Fallback if name isn't found anywhere: lint the first line
77+ if (is.na(location $ start )) {
78+ location $ start <- 1L
79+ location $ end <- nchar(line )
80+ }
81+
82+ Lint(
83+ filename = source_file $ filename ,
84+ line_number = org_line_num ,
85+ column_number = location $ start ,
86+ type = " warning" ,
87+ message = row $ message ,
88+ line = line ,
89+ ranges = list (c(location $ start , location $ end ))
90+ )
91+ }
92+ )
7693 })
7794 })
7895}
@@ -139,23 +156,38 @@ parse_check_usage <- function(expression) {
139156 try(codetools :: checkUsage(expression , report = report ))
140157
141158 function_name <- rex(anything , " : " )
142- line_info <- rex(" " , " (" , capture(name = " path" , non_spaces ), " :" , capture(name = " line_number" , digits ), " )" )
143-
144- res <- re_matches(vals ,
145- rex(function_name ,
146- capture(name = " message" , anything ,
147- one_of(quote , " \u 2018" ), capture(name = " name" , anything ), one_of(quote , " \u 2019" ),
148- anything ),
149- line_info ))
159+ line_info <- rex(" " , " (" , capture(name = " path" , non_spaces ), " :" ,
160+ capture(name = " line1" , digits ), maybe(" -" , capture(name = " line2" , digits )), " )" )
161+
162+ res <- re_matches(
163+ vals ,
164+ rex(
165+ function_name ,
166+ capture(
167+ name = " message" ,
168+ anything ,
169+ one_of(quote , " \u 2018" ),
170+ capture(name = " name" , anything ),
171+ one_of(quote , " \u 2019" ),
172+ anything
173+ ),
174+ line_info
175+ )
176+ )
150177
151178 missing <- is.na(res $ message )
152179 if (any(missing )) {
153- res [missing , ] <- re_matches(vals [missing ],
154- rex(function_name ,
155- capture(name = " message" ,
156- " possible error in " , capture(name = " name" , anything ), " : " , anything
157- ),
158- line_info ))
180+ res [missing , ] <- re_matches(
181+ vals [missing ],
182+ rex(
183+ function_name ,
184+ capture(
185+ name = " message" ,
186+ " possible error in " , capture(name = " name" , anything ), " : " , anything
187+ ),
188+ line_info
189+ )
190+ )
159191 }
160192
161193 res
0 commit comments