Annotation Type CreatesMustCallFor
-
@Target(METHOD) @InheritedAnnotation @Retention(RUNTIME) @Repeatable(List.class) public @interface CreatesMustCallFor
Indicates that the method resets the expression's must-call type to its declared type. This effectively undoes flow-sensitive type refinement. The expression is thevalue
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")
, theexpression
'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 ofobj
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 alarms (warnings at correct code), but never to missed alarms (lack of warnings at incorrect code).
As an example, consider the following code, which uses a
@CreatesMustCallFor
annotation to indicate that thereset()
method re-assigns thesocket
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 ofSocketContainer
is permitted to callreset()
arbitrarily many times. Each time it does so, a newSocket
might be created. ASocketContainer
's must-call obligation of "stop" is fulfilled only ifstop()
is called after the last call toreset()
. The@CreatesMustCallFor
annotation onreset()
's declaration enforces this requirement: at any call toreset()
, 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 freshSocketContainer
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.- See the Checker Framework Manual:
- Resource Leak Checker
-
-
Optional Element Summary
Optional Elements Modifier and Type Optional Element Description java.lang.String
value
Returns the expression whose must-call type is reset after a call to a method with this annotation.
-
-
-
Element Detail
-
value
@JavaExpression java.lang.String value
Returns the expression whose must-call type is reset after a call to a method with this annotation. The expression must be visible in the scope immediately before each call site, so it can only refer to fields, the method's parameters (which should be referenced via the "#X" syntax, where "#1" is the first argument, #2 is the second, etc.), or"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 areset.not.owning
error is issued.- Returns:
- the expression to which must-call obligations are added when the annotated method is invoked
- Default:
- "this"
-
-