Skip to content

Commit e6cfd4e

Browse files
New quotes_linter() to replace single_quotes_linter() (#1931)
* rename file * new quotes_linter to replace single_quote_linter * rm newline * fix documentation * missing @export tag * consistently use 4.1.0, not 4.1 in skips * missing configurable tag * #nolint for apparent false positive * Update NEWS.md Co-authored-by: Indrajeet Patil <[email protected]> * argument is delimiter * fix NEWS and tests for new name * Update NEWS.md Co-authored-by: Indrajeet Patil <[email protected]> * Update NEWS.md Co-authored-by: Indrajeet Patil <[email protected]> * Update R/quotes_linter.R Co-authored-by: Indrajeet Patil <[email protected]> * blank line --------- Co-authored-by: Indrajeet Patil <[email protected]>
1 parent 4f12a43 commit e6cfd4e

25 files changed

+274
-170
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ Collate:
139139
'path_utils.R'
140140
'pipe_call_linter.R'
141141
'pipe_continuation_linter.R'
142+
'quotes_linter.R'
142143
'redundant_equals_linter.R'
143144
'redundant_ifelse_linter.R'
144145
'regex_subset_linter.R'
@@ -147,7 +148,6 @@ Collate:
147148
'seq_linter.R'
148149
'settings.R'
149150
'settings_utils.R'
150-
'single_quotes_linter.R'
151151
'sort_linter.R'
152152
'spaces_inside_linter.R'
153153
'spaces_left_parentheses_linter.R'

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ export(paren_brace_linter)
103103
export(paste_linter)
104104
export(pipe_call_linter)
105105
export(pipe_continuation_linter)
106+
export(quotes_linter)
106107
export(redundant_equals_linter)
107108
export(redundant_ifelse_linter)
108109
export(regex_subset_linter)

NEWS.md

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# lintr (development version)
22

3+
## Deprecations
4+
5+
* `single_quotes_linter()` is deprecated in favor of the more generalizable `quotes_linter()` (#1729, @MichaelChirico).
6+
* `unneeded_concatentation_linter()` is deprecated in favor of `unnecessary_concatenation_linter()` for naming consistency (#1707, @IndrajeetPatil).
7+
38
## Bug fixes
49

510
* `fixed_regex_linter()` is more robust to errors stemming from unrecognized escapes (#1545, #1845, @IndrajeetPatil).
@@ -44,14 +49,14 @@
4449
the style guide on handling this case awaits clarification: https://github.com/tidyverse/style/issues/191.
4550
(#1346, @MichaelChirico)
4651

47-
* The new `indentation_linter()` is part of the default linters. See "New linters" for more details.
48-
49-
* For naming consistency, `unneeded_concatenation_linter()` has been deprecated in favor of
50-
`unnecessary_concatenation_linter()` (#1797, @IndrajeetPatil).
51-
5252
* `undesirable_function_linter()` and `undesirable_operator_linter()` now produce an error
5353
if empty vector of undesirable functions or operators is provided (#1867, @IndrajeetPatil).
5454

55+
* New linters which are also included as defaults (see "New linters" for more details):
56+
+ `indentation_linter()`
57+
+ `quotes_linter()`
58+
+ `unnecessary_concatenation_linter()`
59+
5560
## New and improved features
5661

5762
* New `get_r_string()` helper to get the R-equivalent value of a string, especially useful for R-4-style raw strings.
@@ -131,6 +136,10 @@
131136

132137
* `implicit_assignment_linter()` for checking implicit assignments in function calls (@IndrajeetPatil and @AshesITR, #1777).
133138

139+
* `quotes_linter()` is a generalized version of (now deprecated) `single_quotes_linter()`. It accepts an argument `delimiter` to specify whether `"` or `'` should be the accepted method for delimiting character literals. The default, `"`, reflects the Tidyverse style guide recommendation and matches the behavior of `single_quotes_linter()`.
140+
141+
* `unnecessary_concatenation_linter()` is simply `unneeded_concatenation_linter()`, renamed.
142+
134143
## Notes
135144

136145
* {lintr} now depends on R version 3.5.0, in line with the tidyverse policy for R version compatibility.

R/lintr-deprecated.R

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,3 +213,16 @@ find_column_fun <- function(content, newline_locs) {
213213
line_number - newline_locs[matched_line_number]
214214
}
215215
}
216+
217+
#' Single quotes linter
218+
#' @rdname lintr-deprecated
219+
#' @export
220+
single_quotes_linter <- function() {
221+
lintr_deprecated(
222+
old = "single_quotes_linter",
223+
new = "quotes_linter",
224+
version = "3.1.0",
225+
type = "Linter"
226+
)
227+
quotes_linter()
228+
}

R/quotes_linter.R

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#' Character string quote linter
2+
#'
3+
#' Check that the desired quote delimiter is used for string constants.
4+
#'
5+
#' @param delimiter Which quote delimiter to accept. Defaults to the tidyverse
6+
#' default of `"` (double-quoted strings).
7+
#'
8+
#' @examples
9+
#' # will produce lints
10+
#' lint(
11+
#' text = "c('a', 'b')",
12+
#' linters = quotes_linter()
13+
#' )
14+
#'
15+
#' # okay
16+
#' lint(
17+
#' text = 'c("a", "b")',
18+
#' linters = quotes_linter()
19+
#' )
20+
#'
21+
#' code_lines <- "paste0(x, '\"this is fine\"')"
22+
#' writeLines(code_lines)
23+
#' lint(
24+
#' text = code_lines,
25+
#' linters = quotes_linter()
26+
#' )
27+
#'
28+
#' # okay
29+
#' lint(
30+
#' text = "c('a', 'b')",
31+
#' linters = quotes_linter(delimiter = "'")
32+
#' )
33+
#'
34+
#' @evalRd rd_tags("quotes_linter")
35+
#' @seealso
36+
#' - [linters] for a complete list of linters available in lintr.
37+
#' - <https://style.tidyverse.org/syntax.html#character-vectors>
38+
#' @export
39+
quotes_linter <- function(delimiter = c('"', "'")) {
40+
delimiter <- match.arg(delimiter)
41+
if (delimiter == '"') {
42+
quote_regex <- rex(
43+
start,
44+
zero_or_one(character_class("rR")),
45+
single_quote,
46+
any_non_double_quotes,
47+
single_quote,
48+
end
49+
)
50+
lint_message <- "Only use double-quotes." # nolint: object_usage_linter. An apparent codetools bug.
51+
} else {
52+
quote_regex <- rex(
53+
start,
54+
zero_or_one(character_class("rR")),
55+
double_quote,
56+
any_non_single_quotes,
57+
double_quote,
58+
end
59+
)
60+
lint_message <- "Only use single-quotes."
61+
}
62+
63+
Linter(function(source_expression) {
64+
if (!is_lint_level(source_expression, "file")) {
65+
return(list())
66+
}
67+
68+
content <- source_expression$full_parsed_content
69+
str_idx <- which(content$token == "STR_CONST")
70+
quote_matches <- which(re_matches(content[str_idx, "text"], quote_regex))
71+
72+
lapply(
73+
quote_matches,
74+
function(id) {
75+
with(content[str_idx[id], ], {
76+
line <- source_expression$file_lines[[line1]]
77+
col2 <- if (line1 == line2) col2 else nchar(line)
78+
Lint(
79+
filename = source_expression$filename,
80+
line_number = line1,
81+
column_number = col1,
82+
type = "style",
83+
message = lint_message,
84+
line = line,
85+
ranges = list(c(col1, col2))
86+
)
87+
})
88+
}
89+
)
90+
})
91+
}

R/single_quotes_linter.R

Lines changed: 0 additions & 68 deletions
This file was deleted.

R/zzz.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ default_linters <- modify_defaults(
2929
object_usage_linter(),
3030
paren_body_linter(),
3131
pipe_continuation_linter(),
32+
quotes_linter(),
3233
semicolon_linter(),
3334
seq_linter(),
34-
single_quotes_linter(),
3535
spaces_inside_linter(),
3636
spaces_left_parentheses_linter(),
3737
T_and_F_symbol_linter(),

inst/lintr/linters.csv

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,15 @@ paren_brace_linter,style readability deprecated
6161
paste_linter,best_practices consistency configurable
6262
pipe_call_linter,style readability
6363
pipe_continuation_linter,style readability default
64+
quotes_linter,style consistency readability default configurable
6465
redundant_equals_linter,best_practices readability efficiency common_mistakes
6566
redundant_ifelse_linter,best_practices efficiency consistency configurable
6667
regex_subset_linter,best_practices efficiency
6768
routine_registration_linter,best_practices efficiency robustness
6869
semicolon_linter,style readability default configurable
6970
semicolon_terminator_linter,style readability deprecated configurable
7071
seq_linter,robustness efficiency consistency best_practices default
71-
single_quotes_linter,style consistency readability default
72+
single_quotes_linter,style consistency readability deprecated
7273
sort_linter,readability best_practices efficiency
7374
spaces_inside_linter,style readability default
7475
spaces_left_parentheses_linter,style readability default

man/configurable_linters.Rd

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/consistency_linters.Rd

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)