Skip to content

Commit 148d283

Browse files
authored
Merge pull request #722 from jimhester/fix/451-commented-code
2 parents eb8e57f + 5c75e71 commit 148d283

File tree

3 files changed

+32
-23
lines changed

3 files changed

+32
-23
lines changed

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
* Set the default `complexity_limit` in `cyclocomp_linter` to 15. This is the same complexity limit that is enforced via
4646
`default_linters` (#693, #695, @AshesITR).
4747
* `lint_package()` now lints files in the `demo` directory by default (#703, @dmurdoch).
48+
* `commented_code_linter()` uses the parse tree to find comments, eliminating some false positives (#451, @AshesITR)
4849

4950
# lintr 2.0.1
5051

R/comment_linters.R

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -27,37 +27,42 @@ ops <- list(
2727
#' blocks
2828
#' @export
2929
commented_code_linter <- function(source_file) {
30-
res <- re_matches(source_file$file_lines,
31-
rex(some_of("#"), any_spaces,
32-
capture(name = "code",
33-
# except("'"),
34-
anything,
35-
or(some_of("{}[]"), # code-like parentheses
36-
or(ops), # any operator
37-
group(graphs, "(", anything, ")"), # a function call
38-
group("!", alphas) # a negation
39-
),
40-
anything
41-
)
42-
),
43-
global = FALSE, locations = TRUE)
30+
if (is.null(source_file$full_xml_parsed_content)) return(list())
31+
all_comment_nodes <- xml2::xml_find_all(source_file$full_xml_parsed_content, "//COMMENT")
32+
all_comments <- xml2::xml_text(all_comment_nodes)
33+
code_candidates <- re_matches(
34+
all_comments,
35+
rex(some_of("#"), any_spaces,
36+
capture(name = "code",
37+
# except("'"),
38+
anything,
39+
or(some_of("{}[]"), # code-like parentheses
40+
or(ops), # any operator
41+
group(graphs, "(", anything, ")"), # a function call
42+
group("!", alphas) # a negation
43+
),
44+
anything
45+
)
46+
),
47+
global = FALSE, locations = TRUE)
4448

45-
line_numbers <- rownames(na.omit(res))
46-
lapply(line_numbers, function(line_number) {
47-
line <- source_file$file_lines[as.numeric(line_number)]
48-
is_parsable <- parsable(substr(line,
49-
res[line_number, "code.start"],
50-
res[line_number, "code.end"]))
49+
lapply(rownames(na.omit(code_candidates)), function(code_candidate) {
50+
is_parsable <- parsable(code_candidates[code_candidate, "code"])
5151
if (is_parsable) {
52+
comment_node <- all_comment_nodes[[as.integer(code_candidate)]]
53+
line_number <- as.integer(xml2::xml_attr(comment_node, "line1"))
54+
column_offset <- as.integer(xml2::xml_attr(comment_node, "col1")) - 1L
55+
5256
Lint(
5357
filename = source_file$filename,
5458
line_number = line_number,
55-
column_number = res[line_number, "code.start"],
59+
column_number = column_offset + code_candidates[line_number, "code.start"],
5660
type = "style",
5761
message = "Commented code should be removed.",
58-
line = line,
62+
line = source_file$file_lines[line_number],
5963
linter = "commented_code_linter",
60-
ranges = list(c(res[line_number, "code.start"], res[line_number, "code.end"]))
64+
ranges = list(column_offset + c(code_candidates[line_number, "code.start"],
65+
code_candidates[line_number, "code.end"]))
6166
)
6267
}
6368
})

tests/testthat/test-commented_code_linter.R

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,7 @@ test_that("returns the correct linting", {
5252

5353
expect_lint("1+1 # cat('123')", msg, linter)
5454
expect_lint("#expect_ftype(1e-12 , t)", msg, linter)
55+
56+
# regression test for #451
57+
expect_lint("c('#a#' = 1)", NULL, linter)
5558
})

0 commit comments

Comments
 (0)