Skip to content

Writing robust, performant linters

Michael Chirico edited this page Jul 27, 2023 · 8 revisions

Accumulated knowledge on best practice writing linters

The {lintr} codebase has a lot of accumulated knowledge about how to write robust and fast linters. This Wiki exists as a repository for tidbits on these topics.

It exists as a Wiki to make editing it open to all and with low overhead.

Tips for robustness

  • When writing a test for logical constants like TRUE or FALSE, if you want the condition to match the shorthands T and F, note that the former is a NUM_CONST while the latter is a SYMBOL (c.f. getParseData(parse(text = "TRUE; T")))

Tips for performance

  • Avoid //* XPaths like the plague! At least in the current {xml2}, it is almost always slower than alternatives. A good example is https://github.com/r-lib/lintr/pull/2025, which shows a 3x speed-up from avoiding //* even though the replacement is a long, inefficient-seeming chain of //A[expr] | //B[expr]-style repetitive expressions.
  • Similarly, avoid //expr XPaths. See https://github.com/r-lib/lintr/issues/1358 -- more than 1/3 of all nodes are <expr>, so //expr only eliminates a relatively small portion of the parse tree. The more specific a node you can anchor on, the better, but the difference among nodes besides <expr> is not as important, so err on the side of readability/comprehensibility.
Clone this wiki locally