unnecessary_nesting_linter: Block instances of unnecessary nesting

View source: R/unnecessary_nesting_linter.R

unnecessary_nesting_linterR Documentation

Block instances of unnecessary nesting

Description

Excessive nesting harms readability. Use helper functions or early returns to reduce nesting wherever possible.

Usage

unnecessary_nesting_linter(
  allow_assignment = TRUE,
  allow_functions = c("switch", "try", "tryCatch", "withCallingHandlers", "quote",
    "expression", "bquote", "substitute", "with_parameters_test_that", "reactive",
    "observe", "observeEvent", "renderCachedPlot", "renderDataTable", "renderImage",
    "renderPlot", "renderPrint", "renderTable", "renderText", "renderUI")
)

Arguments

allow_assignment

Logical, default TRUE, in which case braced expressions consisting only of a single assignment are skipped. if FALSE, all braced expressions with only one child expression are linted. The TRUE case facilitates interaction with implicit_assignment_linter() for certain cases where an implicit assignment is necessary, so a braced assignment is used to further distinguish the assignment. See examples.

allow_functions

Character vector of functions which always allow one-child braced expressions. testthat::test_that() is always allowed because testthat requires a braced expression in its code argument. The other defaults similarly compute on expressions in a way which is worth highlighting by em-bracing them, even if there is only one expression, while switch() is allowed for its use as a control flow analogous to if/⁠else⁠.

Tags

best_practices, configurable, consistency, readability

See Also

  • cyclocomp_linter() for another linter that penalizes overly complex code.

  • linters for a complete list of linters available in lintr.

Examples

# will produce lints
code <- "if (A) {\n  stop('A is bad!')\n} else {\n  do_good()\n}"
writeLines(code)
lint(
  text = code,
  linters = unnecessary_nesting_linter()
)

code <- "tryCatch(\n  {\n    foo()\n  },\n  error = identity\n)"
writeLines(code)
lint(
  text = code,
  linters = unnecessary_nesting_linter()
)

code <- "expect_warning(\n  {\n    x <- foo()\n  },\n  'warned'\n)"
writeLines(code)
lint(
  text = code,
  linters = unnecessary_nesting_linter(allow_assignment = FALSE)
)

writeLines("if (x) { \n  if (y) { \n   return(1L) \n  } \n}")
lint(
  text = "if (x) { \n  if (y) { \n   return(1L) \n  } \n}",
  linters = unnecessary_nesting_linter()
)

lint(
  text = "my_quote({x})",
  linters = unnecessary_nesting_linter()
)

# okay
code <- "if (A) {\n  stop('A is bad because a.')\n} else {\n  stop('!A is bad too.')\n}"
writeLines(code)
lint(
  text = code,
  linters = unnecessary_nesting_linter()
)

code <- "capture.output({\n  foo()\n})"
writeLines(code)
lint(
  text = code,
  linters = unnecessary_nesting_linter()
)

code <- "expect_warning(\n  {\n    x <- foo()\n  },\n  'warned'\n)"
writeLines(code)
lint(
  text = code,
  linters = unnecessary_nesting_linter()
)

writeLines("if (x && y) { \n  return(1L) \n}")
lint(
  text = "if (x && y) { \n  return(1L) \n}",
  linters = unnecessary_nesting_linter()
)

writeLines("if (x) { \n  y <- x + 1L\n  if (y) { \n   return(1L) \n  } \n}")
lint(
  text = "if (x) { \n  y <- x + 1L\n  if (y) { \n   return(1L) \n  } \n}",
  linters = unnecessary_nesting_linter()
)

lint(
  text = "my_quote({x})",
  linters = unnecessary_nesting_linter(allow_functions = "my_quote")
)


r-lib/lintr documentation built on Dec. 20, 2024, 7:24 p.m.