@Target(value=METHOD) @InheritedAnnotation @Retention(value=RUNTIME) @Repeatable(value=CreatesMustCallFor.List.class) public @interface CreatesMustCallFor
value
argument/element. More precisely, a call to a method annotated by this annotation changes the
expression's must-call type to the least upper bound of its current must-call type and its
declared must-call type.
When calling a method annotated as @CreatesMustCallFor("
expression")
,
the expression
's static type in the Called Methods type system must be @
CalledMethods
({})
. That is, expression
's CalledMethods type must be empty.
@CreatesMustCallFor("obj")
must be written on any method that assigns a non-final,
owning field of obj
whose declared type has a must-call obligation.
Because this annotation can only add obligations, it can be written safely on any method, even one that does not actually create a new obligation. Writing this annotation on a method that does not actually create any new obligations may lead to false positives, but never to false negatives.
As an example, consider the following code, which uses a @CreatesMustCallFor
annotation to indicate that the reset()
method re-assigns the socket
field:
@MustCall("stop") class SocketContainer { // Note that @MustCall("close") is the default type for java.net.Socket, but it // is included on the next line for illustrative purposes. This example would function // identically if that qualifier were omitted. private @Owning @MustCall("close") Socket socket = ...; @EnsuresCalledMethods(value="this.socket", methods="close") public void stop() throws IOException { socket.close(); } @CreatesMustCallFor("this") public void reset() { if (socket.isClosed()) { socket = new Socket(...); } } }A client of
SocketContainer
is permitted to call reset()
arbitrarily many times.
Each time it does so, a new Socket
might be created. A SocketContainer
's
must-call obligation of "stop" is fulfilled only if stop()
is called after the last call
to reset()
. The @CreatesMustCallFor
annotation on reset()
's declaration
enforces this requirement: at any call to reset()
, all called-methods information about
the receiver is removed from the store of the Must Call Checker and the store of the Called
Methods Checker, so the client has to "start over" as if a fresh SocketContainer
object
had been created.
When the -AnoCreatesMustCallFor
command-line argument is passed to the checker, this
annotation is ignored and all fields are treated as non-owning.
@JavaExpression public abstract String value
"this"
. The
default is "this"
. At call-sites, the viewpoint-adapted referent of expression must be
owning (an owning field, a local variable tracked in a resource alias set, etc.) or a reset.not.owning
error is issued.