
org.checkerframework.dataflow.qual.Deterministic Maven / Gradle / Ivy
Show all versions of dataflow Show documentation
package org.checkerframework.dataflow.qual;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* A method is called deterministic if it returns the same value
* (according to ==
) every time it is called with the same
* parameters and in the same environment. The parameters include the
* receiver, and the environment includes all of the Java heap (that is,
* all fields of all objects and all static variables).
*
* This annotation is important to pluggable type-checking because, after a
* call to a @Deterministic
method, flow-sensitive type refinement
* can assume that anything learned about the first invocation is true
* about subsequent invocations (so long as no non-@
{@link
* SideEffectFree} method call intervenes). For example,
* the following code never suffers a null pointer
* exception, so the Nullness Checker need not issue a warning:
*
if (x.myDeterministicMethod() != null) {
x.myDeterministicMethod().hashCode();
}
*
* Note that @Deterministic
guarantees that the result is
* identical according to ==
, not equal according to
* equals
. This means that writing @Deterministic
on a
* method that returns a reference is often erroneous unless the
* returned value is cached or interned.
*
* Also see {@link Pure}, which means both deterministic and {@link
* SideEffectFree}.
*
* Analysis:
* The Checker Framework performs a conservative analysis to verify a
* @Deterministic
annotation. The Checker Framework issues a
* warning if the method uses any of the following Java constructs:
*
* - Assignment to any expression, except for local variables (and method
* parameters).
*
- A method invocation of a method that is not {@link Deterministic}.
*
- Construction of a new object.
*
- Catching any exceptions. This is to prevent a method to get a hold of
* newly created objects and using these objects (or some property thereof)
* to change their return value. For instance, the following method must be
* forbidden.
*
@Deterministic
int f() {
try {
int b = 0;
int a = 1/b;
} catch (Throwable t) {
return t.hashCode();
}
return 0;
}
*
* A constructor can be @Pure
, but a constructor invocation is
* not deterministic since it returns a different new object each time.
* TODO: Side-effect-free constructors could be allowed to set their own fields.
*
*
* Note that the rules for checking currently imply that every {@code
* Deterministic} method is also {@link SideEffectFree}. This might change
* in the future; in general, a deterministic method does not need to be
* side-effect-free.
*
*
* These rules are conservative: any code that passes the checks is
* deterministic, but the Checker Framework may issue false positive
* warnings, for code that uses one of the forbidden constructs but is
* deterministic nonetheless.
*
*
* In fact, the rules are so conservative that checking is currently
* disabled by default, but can be enabled via the
* -AcheckPurityAnnotations
command-line option.
*
*
* @checker_framework.manual #type-refinement-purity Side effects, determinism, purity, and flow-sensitive analysis
*
* @author Stefan Heule
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.CONSTRUCTOR })
public @interface Deterministic {
}