Annotation 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 the 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 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 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.

See the Checker Framework Manual:
Resource Leak Checker
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static @interface 
    A wrapper annotation that makes the CreatesMustCallFor annotation repeatable.
  • Optional Element Summary

    Optional Elements
    Modifier and Type
    Optional Element
    Description
    Returns the expression whose must-call type is reset after a call to a method with this annotation.
  • Element Details

    • 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 a reset.not.owning error is issued.
      Returns:
      the expression to which must-call obligations are added when the annotated method is invoked
      Default:
      "this"