Diagnostic codes
unresolved
! I could not resolve `validte_url` in this package, its imports, or builtins. Did you mean `validate_url`? --[R/a.R:2:22] 1 | validate_url <- function(x) TRUE 2 | check <- function(x) validte_url(x) | ^^^^^^^^^^^Every finding starts with its code, here unresolved. The code stays the same when the wording of
a message changes, so it is what you name in a suppression, in ry.toml, and in the JSON output.
! marks a warning and x an error (⚠ and × in a terminal). The carets underline exactly what the finding is about, such
as one name, not the whole statement.
Suppressing a finding
Section titled “Suppressing a finding”total = 1L # ry: allow(assignment-operator)
# ry: allow(unused, naming-style)scratchValue <- 1LA suppression covers its own line and the line below, so it works at the end of a line or on the line
above. allow(all) covers every code. There is no block or file scope, because a suppression marks
one exception you have reviewed and should not hide findings in code written later. To turn a code
off everywhere, use ry.toml, and to turn type checking off for one
file, put # typing: off in it.
The marker is found by scanning the line for its first #, so #ry:allow(x) and
# roughly: allow(x) work too, but a # inside a string earlier on the line hides it. Findings on
NAMESPACE, ry.toml, and stub files cannot be suppressed, because they have no R line to carry the
comment.
Some R idioms silence findings on their own:
utils::globalVariables(c("a", "b"))at the top level stopsaandbfrom being reported as unresolved, as it does forR CMD check.- In a file that calls
R6Class(),self,private, andsuperresolve. - A name created with
<<-anywhere in a file resolves in that file. - A name that starts with
.or_is never reported as unused.
On by default
Section titled “On by default”syntax-error (error): code R would refuse to parse, or an assignment target R would refuse to
run, such as 1 + a <- 2. A parse error names what is missing, stays on the line that caused it, and
hides every other finding in the broken statement, because ry draws no conclusions from code it
could not read. Strict mode can still report an undetermined type there.
annotation (error): a #: comment that is malformed, names a type that does not exist, or
annotates nothing, and an unknown # typing: value. It is reported even in files with type checking
off, because a broken annotation is a mistake either way.
unresolved (warning): a name that is defined nowhere ry can see, with a suggestion for a near
miss. It also covers pkg::name where pkg does not export name, and an unknown package.
pkg:::name is exempt, because it reaches internal names on purpose. In NAMESPACE, an
importFrom of a name the package does not export and an export of a name you never define are
errors, because R refuses to load such a package. Attaching a package ry knows nothing about turns
off this check for bare names, as stubs explains.
unused (warning): an assignment nothing reads. In a package, top-level definitions are exempt,
because another file may use them.
duplicate (warning): a top-level name defined in more than one place in a package, where R
silently keeps whichever is collated last. Both definitions are reported.
assignment-operator (warning): = used for assignment, where <- says unambiguously that the
line assigns rather than passes an argument.
boolean-shorthand (warning): T or F, which are ordinary variables that any code can
reassign, unlike TRUE and FALSE.
trailing-comma (error): a comma after a call’s last argument. R reads it as an empty argument,
so c(1, 2, ) fails when it runs.
stub (error): a line in your stubs/*.Rtypes files that ry could not load, so a broken
declaration is never dropped in silence.
config (error): invalid TOML or a value of the wrong type in ry.toml. The language server
marks the line in ry.toml, while ry check stops with exit status 2 instead of reporting it.
Opt-in
Section titled “Opt-in”type-mismatch (error), with [check] typing = true or # typing: on: a value of the wrong
type, a call with the wrong arguments, a field that does not exist, and every other rule in the
type system.
strict (error), with [check] strict = true or # typing: strict: each place where a value’s
type could not be determined, and each name that resolves only because an unknown package was
attached. It also raises unresolved from a warning to an error, so a gate on
--min-severity error counts it.
maybe-undefined (warning), with [check] maybe-undefined = true: a read that some path reaches
before any write, which R reports as object 'v' not found on that path. It is off because it treats
conditions that always agree as independent, so if (ok) v <- 1 followed by if (ok) print(v) is
reported although it is safe.
naming-style (warning), with [lint] naming-style = "snake_case" or "camelCase": a variable
or parameter in the other style. SCREAMING_SNAKE_CASE always conforms.
unused-parameter (off by default): a parameter the body never reads. S3 generics and methods
are exempt, because the generic dictates their parameters.
unused-import (off by default): an importFrom in NAMESPACE whose name your code never
mentions. Only ry check reports it.
shadows-builtin and shadows-namespace (off by default): a top-level name that hides a
function from base, or from another package, such as defining your own filter while
stats::filter exists.
These four take a level in [lint], such as "warn" or "error". An older missing-comma key is
still accepted and does nothing, because f(1 2) is now a syntax error, as it is in R.