blob: eb2f2319d705d217bdbb1ef45d682ab11dd569e5 [file] [log] [blame]
\htmlhr
\chapterAndLabel{Suppressing warnings}{suppressing-warnings}
%% This feels redundant.
% The Checker Framework is sound: whenever your code contains an error, the
% Checker Framework will warn you about the error. The Checker Framework is
% conservative: it may issue warnings when your code is safe and never
% misbehaves at run time.
When the Checker Framework reports a warning, it's best to fix the
underlying problem, by changing the code or its annotations. For each
warning, follow the methodology in Section~\ref{handling-warnings} to
correct the underlying problem.
This section describes what to do if the methodology of
Section~\ref{handling-warnings} indicates that you need to suppress the
warning. You won't change your code, but you will prevent the Checker
Framework from reporting this particular warning to you. (Changing the
code to fix a bug is another way to prevent the Checker Framework from
issuing a warning, but it is not what this chapter is about.)
You may wish to suppress checker warnings because of unannotated libraries
or un-annotated portions of your own code, because of application
invariants that are beyond the capabilities of the type system, because of
checker limitations, because you are interested in only some of the
guarantees provided by a checker, or for other reasons.
Suppressing a warning is similar to writing a cast in a Java
program: the programmer knows more about the type than the type system does
and uses the warning suppression or cast to convey that information to the
type system.
You can suppress a warning message in a single variable initializer,
method, or class by using the following mechanisms:
\newcounter{lastsinglesuppression}
\begin{itemize}
\item
the \code{@SuppressWarnings} annotation
(Section~\ref{suppresswarnings-annotation}), or
\item
the \code{@AssumeAssertion} string in an \<assert> message (Section~\ref{assumeassertion}).
\end{itemize}
You can suppress warnings throughout the codebase by using the following mechanisms:
\begin{itemize}
\item
the \code{-AsuppressWarnings} command-line option (Section~\ref{suppresswarnings-command-line}),
\item
the \code{-AskipUses} and \code{-AonlyUses} command-line options (Section~\ref{askipuses}),
\item
the \code{-AskipDefs} and \code{-AonlyDefs} command-line options (Section~\ref{askipdefs}),
\item
the \code{-AuseConservativeDefaultsForUncheckedCode=source} command-line
option (Section~\ref{compiling-libraries}),
\item
the \code{-Alint} command-line option enables/disables optional checks (Section~\ref{alint}),
\item
changing the specification of a method (Section~\ref{suppressing-warnings-stub}), or
\item
not running the annotation processor
(Section~\ref{no-processor}).
\end{itemize}
Some type checkers can suppress warnings via
\begin{itemize}
\item
checker-specific mechanisms (Section~\ref{checker-specific-suppression}).
\end{itemize}
\noindent
The rest of this chapter explains these mechanisms in turn.
You can use the \code{-AwarnUnneededSuppressions} command-line option to issue a
warning if a \code{@SuppressWarnings} did not suppress any warnings issued by the current checker.
\sectionAndLabel{\code{@SuppressWarnings} annotation}{suppresswarnings-annotation}
\begin{sloppypar}
You can suppress specific errors and warnings by use of the
\code{@SuppressWarnings} annotation, for example
\code{@SuppressWarnings("interning")} or \code{@SuppressWarnings("nullness")}.
Section~\ref{suppresswarnings-annotation-syntax} explains the syntax of the
argument string.
\end{sloppypar}
A \sunjavadocanno{java.base/java/lang/SuppressWarnings.html}{SuppressWarnings}
annotation may be placed on program declarations such as a local
variable declaration, a method, or a class. It suppresses all warnings
within that program element.
Section~\ref{suppresswarnings-annotation-locations} discusses where the
annotation may be written in source code.
Section~\ref{suppresswarnings-best-practices} gives best practices for
writing \<@SuppressWarnings> annotations.
\subsectionAndLabel{\code{@SuppressWarnings} syntax}{suppresswarnings-annotation-syntax}
The \code{@SuppressWarnings} annotation takes a string argument, in one of
the following forms:
\code{"\emph{checkername}:\emph{messagekey}"},
\code{"\emph{checkername}"},
or
\code{"\emph{messagekey}"}.
The argument \emph{checkername} is the checker name, without ``Checker''.
It is lower case by default, though a checker can choose a different casing.
For
example, if you invoke a checker as
\code{javac -processor MyNiftyChecker ...},
then you would suppress its error messages with
\code{@SuppressWarnings("mynifty")}. (An exception is the Subtyping
Checker, for which you use the annotation name; see
Section~\ref{subtyping-using}.)
Sometimes, a checker honors multiple \emph{checkername} arguments; use
the \code{-AshowSuppressWarningsStrings} command-line option to see them.
The argument \emph{messagekey} is the message key for the error.
Each warning message from the compiler gives the most specific
suppression string that can be used to suppress that warning.
An example is ``\<dereference.of.nullable>'' in
%BEGIN LATEX
\begin{smaller}
%END LATEX
\begin{Verbatim}
MyFile.java:107: error: [dereference.of.nullable] dereference of possibly-null reference myList
myList.add(elt);
^
\end{Verbatim}
%BEGIN LATEX
\end{smaller}
%END LATEX
\noindent
You are allowed to use any substring of a message key, so long as the
substring extends at each end to a period or an end of the key. For
example, to suppress a warning with message key
\code{"assignment"}, you could use
\<@SuppressWarnings("assignment")>,
\<@SuppressWarnings("assignment.type")>,
\<@SuppressWarnings("type.incompatible")>, or other variants.
We recommend using
the longest possible message key; a short message might suppress more
warnings than you expect.
The checkername \<"allcheckers"> means all checkers. Using this is not
recommended, except for messages common to all checkers such as
purity-related messages when using \<-AcheckPurityAnnotations>. If you use
\<"allcheckers">, you run some checker that does not issue any warnings,
and you suply the \<-AwarnUnneededSuppressions> command-line argument, then
the Checker Framework will issue an unsuppressable \<unneeded.suppression>
warning.
The special messagekey ``\<all>'' means to suppress all warnings.
If the \emph{checkername} part is omitted, the \<@SuppressWarnings> applies
to all checkers.
If the \emph{messagekey} part is omitted, the \<@SuppressWarnings> applies
to all messages (it suppresses all warnings from the given checker).
With the \code{-ArequirePrefixInWarningSuppressions} command-line
option, the Checker Framework only suppresses warnings when the string is in
the \code{"\emph{checkername}"} or \code{"\emph{checkername}:\emph{messagekey}"}
format, as in
\<@SuppressWarnings("nullness")> or
\<@SuppressWarnings("nullness:assignment")>.
For example, \<@SuppressWarnings("assignment")> and
\<@SuppressWarnings("all")> have no effect (they are ignored) when
\code{-ArequirePrefixInWarningSuppressions} is used. You can use
\<@SuppressWarnings("allcheckers")> to suppress all Checker Framework
warnings.
%% This is true, but relevant mostly to developers, not users.
% For a list of all message keys for a given checker, see two files:
% \begin{enumerate}
% \item \code{checker-framework/checker/src/org/checkerframework/checker/\emph{checkername}/messages.properties}
% \item \code{checker-framework/framework/src/org/checkerframework/common/basetype/messages.properties}
% \end{enumerate}
%
% \noindent
% You need to check the latter file because
% each checker is built on the \code{basetype} checker and inherits its
% properties.
\subsectionAndLabel{Where \code{@SuppressWarnings} can be written}{suppresswarnings-annotation-locations}
\<@SuppressWarnings> is a declaration annotation, so it may be placed on
program declarations such as a local variable declaration, a method, or a
class. It cannot be used on statements, expressions, or types.
(\<assert> plus \<@AssumeAssertion> can be used between statements and can
affect arbitrary expressions; see Section~\ref{assumeassertion}.)
Always write a \<@SuppressWarnings> annotation on the smallest possible
scope. To reduce the scope of a \<@SuppressWarnings> annotation, it is
sometimes desirable to refactor the code. You might extract an expression
into a local variable, so that warnings can be suppressed just for that
local variable's initializer expression. Likewise, you might extract some
code into a separate method, so that warnings can be suppressed just for
its body. Or, you can use \<@AssumeAssertion> on an \<assert> statement;
see Section~\ref{assumeassertion}.
As an example, consider suppressing a warning at an assignment that you know is
safe. Here is an example that uses the Tainting Checker
(Section~\ref{tainting-checker}). Assume that \<expr> has compile-time
(declared) type \<@Tainted String>, but you know that the run-time value of
\<expr> is untainted.
%BEGIN LATEX
\begin{smaller}
%END LATEX
\begin{Verbatim}
@SuppressWarnings("tainting:cast.unsafe") // expr is untainted because ... [explanation goes here]
@Untainted String myvar = expr;
\end{Verbatim}
%BEGIN LATEX
\end{smaller}
%END LATEX
\noindent
Java does not permit annotations (such as \<@SuppressWarnings>) on
assignments (or on other statements or expressions), so
it would have been \emph{illegal} to write
%BEGIN LATEX
\begin{smaller}
%END LATEX
\begin{Verbatim}
@Untainted String myvar;
...
@SuppressWarnings("tainting:cast.unsafe") // expr is untainted because ...
myvar = expr;
\end{Verbatim}
%BEGIN LATEX
\end{smaller}
%END LATEX
\subsectionAndLabel{Good practices when suppressing warnings}{suppresswarnings-best-practices}
\subsubsectionAndLabel{Suppress warnings in the smallest possible scope}{suppresswarnings-best-practices-smallest-scope}
Prefer \<@SuppressWarnings> on a local variable declaration to one on a method, and
prefer one on a method to one on a class.
\<@SuppressWarnings> on a local variable declaration applies only to the
declaration (including its initializer if any), not to all uses of the variable.
You may be able to suppress a warning about a use of an expression by
writing \<@AssumeAssertion> for the expression, before the use. See
Section~\ref{assumeassertion}.
Another way to reduce the scope of a \<@SuppressWarnings> is to
extract the expression into a new local variable
and place a \code{@SuppressWarnings} annotation on the variable
declaration. See Section~\ref{suppresswarnings-annotation-locations}.
%% I'm not sure how this is related to the smallest possible scope.
% As another example, if you have annotated the signatures but not the bodies
% of the methods in a class or package, put a \code{@SuppressWarnings}
% annotation on the class declaration or on the package's
% \code{package-info.java} file.
\subsubsectionAndLabel{Use a specific argument to \code{@SuppressWarnings}}{suppresswarnings-best-practices-specific-argument}
\label{compiler-message-keys}
It is best to use the most specific possible message key to suppress just a
specific error that you know to be a false positive. The checker outputs
this message key when it issues an error. If you use a broader
\<@SuppressWarnings> annotation, then it may mask other errors that you
needed to know about.
Any of the following would have suppressed the warning in
Section~\ref{suppresswarnings-annotation-locations}:
\begin{Verbatim}
@SuppressWarnings("tainting") // suppresses all tainting-related warnings
@SuppressWarnings("cast") // suppresses warnings from all checkers about casts
@SuppressWarnings("unsafe") // suppresses warnings from all checkers about unsafe code
@SuppressWarnings("cast.unsafe") // suppresses warnings from all checkers about unsafe casts
@SuppressWarnings("tainting:cast") // suppresses tainting warnings about casts
@SuppressWarnings("tainting:unsafe") // suppresses tainting warnings about unsafe code
@SuppressWarnings("tainting:cast.unsafe") // suppresses tainting warnings about unsafe casts
\end{Verbatim}
The last one is the most specific, and therefore is the best style.
\subsubsectionAndLabel{Justify why the warning is a false positive}{suppresswarnings-best-practices-justification}
A \<@SuppressWarnings> annotation asserts that the programmer knows that
the code is actually correct or safe (that is, no undesired behavior will
occur), even though the type system is unable to prove that the code is
correct or safe.
Whenever you write a \<@SuppressWarnings> annotation, you should also
write, typically on the same line, a code comment
explaining why the code is actually correct. In some cases you might also
justify why the code cannot be rewritten in a simpler way that would be
amenable to type-checking. Also make it clear what error is being
suppressed. (This is particularly important when the \<@SuppressWarnings> is
on a method declaration and the suppressed warning might be anywhere in the
method body.)
This documentation will help you and others to understand the reason for
the \<@SuppressWarnings> annotation. It will also help you audit your code
to verify all the warning suppressions. (The code is correct only if the
checker issues no warnings \emph{and} each \<@SuppressWarnings> is correct.)
A suppression message like ``a.f is not null'' is not useful. The fact
that you are suppressing the warning means that you believe that \<a.f> is
not null. The message should explain \emph{why} you believe that; for
example, ``a.f was checked above and no subsequent side effect can affect it''.
Here are some terse examples from libraries in \href{https://github.com/plume-lib/}{plume-lib}:
\begin{Verbatim}
@SuppressWarnings("cast") // cast is redundant (except when checking nullness)
@SuppressWarnings("interning") // FbType.FREE is interned but is not annotated
@SuppressWarnings("interning") // equality testing optimization
@SuppressWarnings("nullness") // used portion of array is non-null
@SuppressWarnings("nullness") // oi.factory is a static method, so null first argument is OK
@SuppressWarnings("purity") // side effect to local state of type BitSet
\end{Verbatim}
A particularly good (and concise) justification is to reference an issue in
the issue tracker, as in these two from \href{https://plse.cs.washington.edu/daikon/}{Daikon}:
\begin{Verbatim}
@SuppressWarnings("flowexpr.parse.error") // https://tinyurl.com/cfissue/862
@SuppressWarnings("keyfor") // https://tinyurl.com/cfissue/877
\end{Verbatim}
\noindent
Please report false positive warnings, then reference them in your warning suppressions.
This permits the Checker Framework maintainers to know about the
problem, it helps them with prioritization (by knowing how often in your
codebase a particular issue arises), and it enables you to know when an
issue has been fixed (though the \<-AwarnUnneededSuppressions> command-line
option also serves the latter purpose).
\sectionAndLabel{\code{@AssumeAssertion} string in an \<assert> message}{assumeassertion}
\begin{sloppypar}
Sometimes, it is too disruptive to refactor your code to create a location
where \<@SuppressWarnings> can be written. You can instead suppress a
warning by writing an assertion whose message contains the string
\<@AssumeAssertion(\emph{checkername})>.
\end{sloppypar}
For example, in this code:
\begin{Verbatim}
while (c != Object.class) {
...
c = c.getSuperclass();
assert c != null
: "@AssumeAssertion(nullness): c was not Object, so its superclass is not null";
}
\end{Verbatim}
\noindent
the Nullness Checker assumes that \<c> is non-null from the \<assert>
statement forward (including on the next iteration through the loop).
The \<assert> expression must be an expression that would affect flow-sensitive
type refinement (Section~\ref{type-refinement}), if the
expression appeared in a conditional test. Each type system has its own
rules about what type refinement it performs.
The value in parentheses is a checker name (typically lowercase),
exactly as in the \<@SuppressWarnings> annotation
(Section~\ref{suppresswarnings-annotation-syntax}).
Any subcheckers will also assume that the
assertion is true (e.g., the Map Key Checker will assume that
the assertion in the example above cannot fail, when it runs
as a subchecker of the Nullness Checker).
The same good practices apply
as for \<@SuppressWarnings> annotations, such as writing a comment
justifying why the assumption is safe
(Section~\ref{suppresswarnings-best-practices}).
The \<-AassumeAssertionsAreEnabled> and \<-AassumeAssertionsAreDisabled>
command-line options (Section~\ref{type-refinement-assertions}) do not
affect processing of \<assert> statements that have \<@AssumeAssertion> in
their message. Writing \<@AssumeAssertion> means that the assertion would
succeed if it were executed, and the Checker Framework makes use of that
information regardless of the \<-AassumeAssertionsAreEnabled> and
\<-AassumeAssertionsAreDisabled> command-line options.
%% Redundant.
% If the string \<@AssumeAssertion(\emph{checkername})> does not appear in the
% assertion message, then the Checker Framework treats the assertion as
% being used for defensive programming. That is, the programmer believes
% that the assertion might fail at run time, so the Checker Framework should
% not make any inference, which would not be justified.
%% Users should never see assertions anyway -- they are for programmers.
% A downside of putting the string in the assertion message is that if the
% assertion ever fails, then a user might see the string and be confused.
% This should never be a problem, since
% the programmer should write the string should only if the programmer has
% reasoned that the
% assertion can never fail.
% (Another way of stating the Nullness Checker's use of assertions is as an
% additional caveat to the guarantees provided by a checker
% (Section~\ref{checker-guarantees}). The Nullness Checker prevents null
% pointer errors in your code under the assumption that assertions are
% enabled, and it does not guarantee that all of your assertions succeed.)
\subsectionAndLabel{Suppressing warnings and defensive programming}{defensive-programming}
This section explains the distinction between two different uses for
assertions: debugging a program (also known as defensive programming)
versus specifying a program. The examples use nullness annotations, but
the concepts apply to any checker.
The purpose of assertions is to aid debugging by throwing an exception
when a program does not work correctly. Sometimes, programmers use assertions for a
different purpose: documenting how
the program works. By default, the Checker Framework assumes that each assertion
is used for its primary purpose of debugging: the assertion might fail at run time, and the programmer
wishes to be informed at compile time about such possible run-time errors.
% Here is an example of an assertion used for debugging.
Suppose that a
programmer encounters a failing test, adds an assertion to aid debugging, and fixes the
test. The programmer leaves the assertion in the program if the programmer
is worried that the program might fail in a similar way in the future.
% The assertion indicates the potential for failure at this point in the code.
The Checker Framework should not assume that the assertion succeeds ---
doing so would defeat the very purpose of the Checker Framework, which is
to detect errors at compile time and prevent them from occurring at run
time.
A non-standard use for annotations is to document facts that a programmer
has independently verified to be true. The Checker Framework can
leverage these assertions in order to avoid issuing false positive
warnings. The programmer marks such assertions with the \<@AssumeAssertion>
string in the \<assert> message (see Section~\ref{assumeassertion}. Only
do so if you are sure that the assertion always succeeds at run time.
\label{assertion-methods}
Methods such as
\sunjavadoc{java.base/java/util/Objects.html\#requireNonNull(T)}{Objects.requireNonNull},
JUnit's \<Assert.assertNotNull>, and
Guava's \<verifyNotNull> and \<checkNotNull> are
similar to assertions. Just as for assertions, their intended use is as
debugging aids, they might fail at run time, and the Checker Framework
warns if that might happen.
Some programmers may use assert methods as documentation of facts
that the programmer has verified in some other manner.
If you know that a particular codebase always uses
an assertion method not for defensive programming but to indicate
facts that are guaranteed to be true (that is, these assertions cannot
fail at run time), then there are two approaches to avoid false positive
warnings: write specifications or suppress
warnings; see below for an explanation of each approach.
The method
\refmethod{checker/nullness/util}{NullnessUtil}{castNonNull}{-T-} is not an
assertion method. It is a warning suppression method.
Note that some libraries have an imprecise specification of their assertion
methods. For example, Guava's \<Verify.verifyNotNull> is imprecisely
specified to have a \<@Nullable> formal parameter. In a correct execution,
\<null> never flows there, so its type can and should be annotated as
\<@NonNull>. That annotation allows the Nullness Checker to warn about
programs that crash due to passing \<null> to \<verifyNotNull>. You can
use a version of Guava with a small change to your build file. Where the
build file refers to Maven Central's \<guava> artifact, change the group
name from ``com.google.guava'' to ``org.checkerframework.annotatedlib''.
(The code is identical; the only difference is annotations.)
\paragraphAndLabel{Option 1: Write specifications based on uses of assertion methods}{specifications-based-on-assertion-methods}
Suppose you are annotating a codebase that already contains precondition checks,
such as:
\begin{Verbatim}
public String myGet(String key, String def) {
checkNotNull(key, "key"); // NOI18N
...
}
\end{Verbatim}
\noindent
Because \<key> is non-null in every correct execution, its type should be
\<@NonNull> in \<myGet>'s signature. (\<@NonNull> is the default, so in
this case there is nothing to write.) The checker will not issue a warning
about the \<checkNotNull> call, but will issue a warning at incorrect calls
to \<myGet>.
\paragraphAndLabel{Option 2: Suppress warnings at uses of assertion methods}{assert-method-suppress-warnings}
This section explains how to suppress warnings at all uses of an assertion
method. As with any warning suppression, you will compromise the checker's
guarantee that your code is correct and will not fail at run time.
\begin{itemize}
\item
If the method is defined in your source code, annotate its definition just as
\refmethod{checker/nullness/util}{NullnessUtil}{castNonNull}{-T-} is
annotated; see its Javadoc or the source code for the Checker Framework.
Also, be sure to document the intention in the method's Javadoc, so that
programmers do not
accidentally misuse it for defensive programming.
\item
If the method is defined in an external library, write a stub file that
changes the method's annotations, or use \<-AskipUses> to make the
Checker Framework ignore all calls to an entire class.
\end{itemize}
\sectionAndLabel{\code{-AsuppressWarnings} command-line option}{suppresswarnings-command-line}
Supplying the \<-AsuppressWarnings> command-line option is equivalent to
writing a \<@SuppressWarnings> annotation on every class that the compiler
type-checks. The argument to \<-AsuppressWarnings> is a comma-separated
list of warning suppression strings, as in
\<-AsuppressWarnings=purity,uninitialized>.
When possible, it is better to write a \<@SuppressWarnings> annotation with a
smaller scope, rather than using the \<-AsuppressWarnings> command-line option.
\sectionAndLabel{\code{-AskipUses} and \code{-AonlyUses} command-line options}{askipuses}
You can suppress all errors and warnings at all \emph{uses} of a given
class, or suppress all errors and warnings except those at uses of a given
class. (The class itself is still type-checked, unless you also use
the \code{-AskipDefs} or \code{-AonlyDefs} command-line option, see~\ref{askipdefs}).
You can also use these options to affect entire packages or directories/folders.
Set the \code{-AskipUses} command-line option to a
regular expression that matches class names (not file names) for which warnings and errors
should be suppressed.
Or, set the \code{-AonlyUses} command-line option to a
regular expression that matches class names (not file names) for which warnings and errors
should be emitted; warnings about uses of all other classes will be suppressed.
For example, suppose that you use
``{\codesize\verb|-AskipUses=^java\.|}'' on the command line
(with appropriate quoting) when invoking
\code{javac}. Then the checkers will suppress all warnings related to
classes whose fully-qualified name starts with \codesize\verb|java.|, such
as all warnings relating to invalid arguments and all warnings relating to
incorrect use of the return value.
To suppress all errors and warnings related to multiple classes, you can use
the regular expression alternative operator ``\code{|}'', as in
``{\codesize\verb+-AskipUses="java\.lang\.|java\.util\."+}'' to suppress
all warnings related to uses of classes that belong to the \code{java.lang} or
\code{java.util} packages. (Depending on your shell or other tool, you
might need to change or remove the quoting.)
You can supply both \code{-AskipUses} and \code{-AonlyUses}, in which case
the \code{-AskipUses} argument takes precedence, and \code{-AonlyUses} does
further filtering but does not add anything that \code{-AskipUses} removed.
Warning: Use the \code{-AonlyUses} command-line option with care,
because it can have unexpected results. For example, if the
given regular expression does not match classes in the JDK, then the
Checker Framework will suppress every warning that involves a JDK class
such as \<Object> or \<String>. The meaning of \code{-AonlyUses} may be
refined in the future. Oftentimes \code{-AskipUses} is more useful.
% The desired meaning of -AonlyUses is tricky, because what is a "use"?
% Maybe only check calls of methods on the class (though don't check
% argument expressions) and field accesses, but nothing else (such as
% extends clauses that happen to use the class). But then we would also
% want to suppress warnings related to assignments where a method use or
% field access is the right-hand side. I'm going to punt on this for now.
\sectionAndLabel{\code{-AskipDefs} and \code{-AonlyDefs} command-line options}{askipdefs}
You can suppress all errors and warnings in the \emph{definition} of a given
class, or suppress all errors and warnings except those in the definition
of a given class. (Uses of the class are still type-checked, unless you also use
the \code{-AskipUses} or \code{-AonlyUses} command-line option,
see~\ref{askipuses}.)
You can also use these options to affect entire packages or directories/folders.
Set the \code{-AskipDefs} command-line option to a
regular expression that matches class names (not file names) in whose definition warnings and errors
should be suppressed.
Or, set the \code{-AonlyDefs} command-line option to a
regular expression that matches class names (not file names) whose
definitions should be type-checked.
(This is somewhat similar to NullAway's
\<-XepOpt:NullAway:AnnotatedPackages> command-line argument.)
For example, if you use
``{\codesize\verb|-AskipDefs=^mypackage\.|}'' on the command line
(with appropriate quoting) when invoking
\code{javac}, then the definitions of
classes whose fully-qualified name starts with \codesize\verb|mypackage.|
will not be checked.
If you supply both \code{-AskipDefs} and \code{-AonlyDefs}, then
\code{-AskipDefs} takes precedence.
Another way not to type-check a file is not to pass it on the compiler
command-line: the Checker Framework type-checks only files that are passed
to the compiler on the command line, and does not type-check any file that
is not passed to the compiler. The \code{-AskipDefs} and \code{-AonlyDefs}
command-line options
are intended for situations in which the build system is hard to understand
or change. In such a situation, a programmer may find it easier to supply
an extra command-line argument, than to change the set of files that is
compiled.
A common scenario for using the arguments is when you are starting out by
type-checking only part of a legacy codebase. After you have verified the
most important parts, you can incrementally check more classes until you
are type-checking the whole thing.
\sectionAndLabel{\code{-Alint} command-line option\label{lint-options}}{alint}
The \code{-Alint} option enables or disables optional checks, analogously to
javac's \code{-Xlint} option.
Each of the distributed checkers supports at least the following lint
options (and possibly more, see the checker's documentation):
% For the current list of lint options supported by all checkers, see
% method BaseTypeChecker.getSupportedLintOptions().
% For the per-checker list, search for "@SupportedLintOptions" in the
% checker implementations.
\begin{itemize}
\item
\code{cast:unsafe} (default: on) warn about unsafe casts that are not
checked at run time, as in \code{((@NonNull String) myref)}. Such casts
are generally not necessary because of type refinement
(Section~\ref{type-refinement}).
\item
\code{cast:redundant} (default: on) warn about redundant
casts that are guaranteed to succeed at run time,
as in \code{((@NonNull String) "m")}. Such casts are not necessary,
because the target expression of the cast already has the given type
qualifier.
\item
\code{cast} Enable or disable all cast-related warnings.
\item
\begin{sloppypar}
\code{all} Enable or disable all lint warnings, including
checker-specific ones if any. Examples include \code{redundantNullComparison} for the
Nullness Checker (see Section~\ref{nullness-lint-nulltest}) and \<dotequals> for
the Interning Checker (see Section~\ref{lint-dotequals}). This option
does not enable/disable the checker's standard checks, just its optional
ones.
\end{sloppypar}
\item
\code{none} The inverse of \<all>: disable or enable all lint warnings,
including checker-specific ones if any.
\end{itemize}
% This syntax is different from -Xlint that uses a colon instead of an
% equals sign, because javac forces the use of the equals sign.
\noindent
To activate a lint option, write \code{-Alint=} followed by a
comma-delimited list of check names. If the option is preceded by a
hyphen (\code{-}), the warning is disabled. For example, to disable all
lint options except redundant casts, you can pass
\code{-Alint=-all,cast:redundant} on the command line.
Only the last \code{-Alint} option is used; all previous \code{-Alint}
options are silently ignored. In particular, this means that \<-Alint=all
-Alint=cast:redundant> is \emph{not} equivalent to
\code{-Alint=-all,cast:redundant}.
\sectionAndLabel{Change the specification of a method}{suppressing-warnings-stub}
To prevent a checker from issuing a warning at calls to a specific method,
you can change the annotations on that method by writing a stub file (see
Section~\ref{stub}).
Stub files are usually used to provide correct specifications for
unspecified code.
Stub files can also be used to provide \emph{incorrect} specifications, for
the purpose of suppressing warnings. For example, suppose that you are
running the Nullness Checker to prevent null pointer exceptions. Further
suppose that for some reason you do not care if method
\<Objects.requireNonNull> crashes with a \<NullPointerException>. You can
supply a stub file containing:
\begin{Verbatim}
package java.util;
class Objects {
@EnsuresNonNull("#1")
public static <T> @NonNull T requireNonNull(@Nullable T obj);
}
\end{Verbatim}
\sectionAndLabel{Don't run the processor}{no-processor}
You can compile parts of your code without use of the
\code{-processor} switch to \code{javac}. No checking is done during
such compilations, so no warnings are issued related to pluggable
type-checking.
You can direct your build system to avoid compiling certain parts of your
code. For example, the \<-Dmaven.test.skip=true> command-line argument
tells Maven not to compile (or run) the tests.
\sectionAndLabel{Checker-specific mechanisms}{checker-specific-suppression}
Finally, some checkers have special rules. For example, the Nullness
checker (Chapter~\ref{nullness-checker}) uses
the special \<castNonNull> method to suppress warnings
(Section~\ref{suppressing-warnings-with-assertions}).
This manual also explains special mechanisms for
suppressing warnings issued by the Fenum Checker
(Section~\ref{fenum-suppressing}) and the Units Checker
(Section~\ref{units-suppressing}).
% LocalWords: quals skipUses un AskipUses Alint annotationname javac's Awarns
% LocalWords: Xlint dotequals castNonNull XDTA Formatter jsr subpart
% LocalWords: unselect checkbox classpath Djsr bak Nullness nullness java lang
% LocalWords: checkername util myref nulltest html ESC buildfile mynifty Fenum
% LocalWords: MyNiftyChecker messagekey basetype uncommenting Anomsgtext
% LocalWords: AskipDefs mypackage Makefile PLXCOMP expr
% LocalWords: TODO AsuppressWarnings AssumeAssertion AonlyUses AonlyDefs
% LocalWords: ing warningkey redundantNullComparison qual proc Decl
% LocalWords: lastsinglesuppression classfiles AwarnUnneededSuppressions
%% LocalWords: AshowSuppressWarningsStrings NullableType NonNullType JUnit's
%% LocalWords: PolyNullType MonotonicNonNullType KeyForType NullableDecl
%% LocalWords: NonNullDecl PolyNullDecl MonotonicNonNullDecl KeyForDecl
%% LocalWords: refactored AassumeAssertionsAreEnabled assertNotNull
%% LocalWords: AassumeAssertionsAreDisabled NullnessUtil checkNotNull
%% LocalWords: ElementType AuseSafeDefaultsForUnannotatedSourceCode
% LocalWords: AuseConservativeDefaultsForUncheckedCode checkerframework askipuses
%% LocalWords: suppresswarnings ArequirePrefixInWarningSuppressions
%% LocalWords: assumeassertion askipdefs alint compat substring myGet
% LocalWords: AcheckPurityAnnotations allcheckers requireNonNull
% LocalWords: verifyNotNull subcheckers subchecker