blob: 5cb1bd15882e3fc3da97e3cb55f9b6b31a323ead [file] [log] [blame]
\htmlhr
\chapterAndLabel{Returns Receiver Checker}{returns-receiver-checker}
The Returns Receiver Checker enables documenting and checking that a method
returns its receiver (i.e., the \<this> parameter).
There are two ways to run the Returns Receiver Checker.
\begin{itemize}
\item
Typically, it is automatically run by another checker.
If the code being checked does not use fluent APIs, you can pass the
\<-AdisableReturnsReceiver> command-line option. This disables the
Returns Receiver Checker and makes the other checker run faster.
\item
Alternately, you can run just the Returns Receiver Checker, by
supplying the following command-line options to javac:
\code{-processor org.checkerframework.common.returnsreceiver.ReturnsReceiverChecker}
\end{itemize}
\sectionAndLabel{Annotations}{returns-receiver-checker-annotations}
The qualifier \refqualclass{common/returnsreceiver/qual}{This} on the return
type of a method indicates that the method returns its receiver. Methods
that return their receiver are common in so-called ``fluent'' APIs. Here
is an example:
\begin{Verbatim}
class MyBuilder {
@This MyBuilder setName(String name) {
this.name = name;
return this;
}
}
\end{Verbatim}
An \refqualclass{common/returnsreceiver/qual}{This} annotation can only be
written on a return type, a receiver type, or in a downcast.
As is standard, the Returns Receiver Checker has a top qualifier,
\refqualclass{common/returnsreceiver/qual}{UnknownThis}, and a bottom qualifier,
\refqualclass{common/returnsreceiver/qual}{BottomThis}.
Programmers rarely need to write these annotations.
Here are additional details. \refqualclass{common/returnsreceiver/qual}{This}
is a polymorphic qualifier rather than a regular type qualifier ((see
Section~\ref{method-qualifier-polymorphism}). Conceptually, a receiver type always has
an \refqualclass{common/returnsreceiver/qual}{This} qualifier. When a method
return type also has an \refqualclass{common/returnsreceiver/qual}{This}
qualifier, the presence of the polymorphic annotation on both the method's
return and receiver type forces their type qualifiers to be \emph{equal}. Hence,
the method will only pass the type checker if it returns its receiver argument,
achieving the desired checking.
\sectionAndLabel{AutoValue and Lombok Support}{returns-receiver-checker-autovalue-lombok-support}
\begin{figure}
\begin{Verbatim}
@AutoValue
abstract class Animal {
abstract String name();
abstract int numberOfLegs();
static Builder builder() {
return new AutoValue_Animal.Builder();
}
@AutoValue.Builder
abstract static class Builder {
abstract Builder setName(String value); // @This is automatically added here
abstract Builder setNumberOfLegs(int value); // @This is automatically added here
abstract Animal build();
}
}
\end{Verbatim}
\caption{User-written code that uses the \<@AutoValue.Builder> annotation.
Given this code,
(1) AutoValue automatically generates a concrete subclass of
\<Animal.Builder>, see Figure~\ref{fig-autovalue-builder-generated}, and
(2) the Returns Receiver Checker automatically adds \<@This> annotations
on setters in both user-written and automatically-generated code.}
\label{fig-autovalue-builder}
\end{figure}
\begin{figure}
\begin{Verbatim}
class AutoValue_Animal {
static final class Builder extends Animal.Builder {
private String name;
private Integer numberOfLegs;
@This Animal.Builder setName(String name) {
this.name = name;
return this;
}
@This Animal.Builder setNumberOfLegs(int numberOfLegs) {
this.numberOfLegs = numberOfLegs;
return this;
}
@Override
Animal build() {
return new AutoValue_Animal(this.name, this.numberOfLegs);
}
}
}
\end{Verbatim}
\caption{Code generated by AutoValue for the example of
Figure~\ref{fig-autovalue-builder}, including the \<@This> annotations added
by the Returns Receiver Checker.}
\label{fig-autovalue-builder-generated}
\end{figure}
The \href{https://github.com/google/auto/tree/master/value}{AutoValue} and
\href{https://projectlombok.org/}{Lombok} projects both support automatic
generation of builder classes, which enable flexible object construction.
For code using these two frameworks, the Returns Receiver Checker
automatically adds \<@This> annotations to setter methods in builder
classes. All the \<@This> annotations in
Figures~\ref{fig-autovalue-builder}
and~\ref{fig-autovalue-builder-generated} are automatically added by the
Returns Receiver Checker.
% LocalWords: UnknownThis BottomThis AutoValue autovalue lombok