Deprecations & breaking changes
- Six linters fully deprecated in the previous release are now removed:
consecutive_stopifnot_linter(),extraction_operator_linter(),no_tab_linter(),single_quotes_linter(),unnecessary_nested_if_linter(), andunneeded_concatenation_linter(). assignment_linter()only allows<-by default, i.e.,<<-is now excluded (consistent with the defaults forundesirable_operator_linter(); #2717, @MichaelChirico).- Arguments
allow_cascading_assign=,allow_right_assign=, andallow_pipe_assign=toassignment_linter()are now removed. Useoperator=instead. - Argument
interpret_gluetoobject_usage_linter(), marked deprecated in the previous release, is now defunct. Useinterpret_extensions=instead; see the 3.3.0-1 release notes and?object_usage_linterfor more.
Bug fixes
- Excluding
cyclocomp_linter()inavailable_linters()orlinters_with_tags(), which requires the weak dependency {cyclocomp}, no longer emits a warning if {cyclocomp} is not available (#2909, @MichaelChirico). repeat_linter()no longer errors whenwhileinwhile (TRUE)is in a column to the right of}(#2828, @MichaelChirico).get_source_expression(lines=)andlint(text=)correctly handle text with unmarked encoding (#3046, @MichaelChirico).lint(exclude=)doesn't fail cryptically when provided a regex with capture groups (#2831, @MichaelChirico).
New and improved features
- Rmd files with explicit
eval=FALSEchunks are skipped (#1964, @MichaelChirico). Complex cases likeeval=objwhereobj=FALSEandopts_chunk$set(eval = FALSE)are not yet supported; the former likely never will be. This obviates the previous workaround requiring such chunks to use plain markdown highlighting gates like```r(i.e., without {knitr} mark-up).
Linter improvements
indentation_linter()correctly enforces the updated Tidyverse guidelines around multi-line function definitions, namely that double-indented functions are no longer recommended, in favor of single-indented formals separated from the function body by a line with) {(#2830, @MichaelChirico).sort_linter()paste_linter()- lints
expression(paste(., sep = ""))because thepasteinside an expression doesn't support thesepargument (#2945, @mcol). - recommends
deparse1(x)in favor ofpaste(deparse(x), collapse = ...)(#2615, @emmanuel-ferdman).
- lints
namespace_linter()detects functions accessed with::or:::when they are already imported into the package'sNAMESPACE(#2081, @MichaelChirico).backport_linter()now exhaustively covers all exported symbols introduced throughout R's history back to R 3.0.0, including many symbols never mentioned in NEWS.- General handling of logic around where comments can appear in code has been improved (#2822, @MichaelChirico). In many cases, this is a tiny robustness fix for weird edge cases unlikely to be found in practice, but in others, this improves practical linter precision (reduced false positives and/or false negatives). The affected linters (with annotations for changes noteworthy enough to have gotten a dedicated bug) are:
brace_linter()coalesce_linter()comparison_negation_linter()#2826conjunct_test_linter()#2827empty_assignment_linter()expect_comparison_linter()fixed_regex_linter()#2827if_switch_linter()ifelse_censor_linter()#2826implicit_assignment_linter()length_test_linter()literal_coercion_linter()#2824matrix_apply_linter()#2825nzchar_linter()#2826object_length_linter()#2827object_name_linter()#2827object_usage_linter()outer_negation_linter()#2827redundant_equals_linter()regex_subset_linter()seq_linter()sort_linter()sprintf_linter()#2827string_boundary_linter()strings_as_factors_linter()unnecessary_concatenation_linter()#2827unnecessary_lambda_linter()#2827unnecessary_nesting_linter()#2827unnecessary_placeholder_linter()unreachable_code_linter()#2827vector_logic_linter()#2826
Lint accuracy fixes: removing false positives
if_switch_linter()- no longer produces a false positive when comparing to empty strings (
"",'', or raw strings likeR"()"), which cannot be used asswitch()case names (#2835, @emmanuel-ferdman). - handles expressions/branches without
{correctly (#3042, @MichaelChirico)
- no longer produces a false positive when comparing to empty strings (
undesirable_operator_linter(call_is_undesirable = FALSE)now correctly skips prefix notation like`:::`(pkg, fun)(#2999, @emmanuel-ferdman).unnecessary_nesting_linter()treats=assignment the same as<-for several pieces of logic (#2245 and #2829, @MichaelChirico).vector_logic_linter()ignores scalar operators (&&/||) inside anonymous functions withinfilter()/subset()(#2935, @emmanuel-ferdman).unnecessary_lambda_linter()skips lambdas with an outer unary operator likesapply(x, \(xi) !all(xi))(#2742, @MichaelChirico).
Notes
- {lintr} now requires R 4.1.0
- Internal code is refactored to avoid
xml2::xml_ns()for e.g. 5-30% end-to-end speed improvement inlint_package()
New Contributors
- @lschneiderbauer made their first contribution in #2862
- @marberts made their first contribution in #2924
- @emmanuel-ferdman made their first contribution in #2938
- @mcol made their first contribution in #2942
- @TimTaylor made their first contribution in #2962
- @clerousset made their first contribution in #2961
Full Changelog: v3.2.0...v3.4.0