Class PurityChecker
SideEffectFree, Deterministic, and Pure) of a statement or expression. The entry point is method
checkPurity(com.sun.source.util.TreePath, org.checkerframework.javacutil.AnnotationProvider, com.sun.source.tree.MethodTree, javax.annotation.processing.ProcessingEnvironment, boolean, boolean, boolean).
This class does not check SideEffectsOnly, which is
the other purity annotation. Verifying @SideEffectsOnly requires parsing the Java
expressions in the annotation and viewpoint-adapting them at each call site, which this module
cannot do. org.checkerframework.common.basetype.DisallowedSideEffects, which
BaseTypeVisitor calls, checks @SideEffectsOnly.
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprotected static classHelper class to keepPurityChecker's interface clean.static classResult of thePurityChecker. -
Method Summary
Modifier and TypeMethodDescriptionstatic PurityChecker.PurityResultcheckPurity(TreePath statement, AnnotationProvider annoProvider, @Nullable MethodTree enclosingMethod, @Nullable ProcessingEnvironment env, boolean assumeSideEffectFree, boolean assumeDeterministic, boolean assumePureGetters) Compute whether the given statement is side-effect-free, deterministic, or both.static PurityChecker.PurityResultcheckPurity(List<TreePath> statements, AnnotationProvider annoProvider, @Nullable MethodTree enclosingMethod, @Nullable ProcessingEnvironment env, boolean assumeSideEffectFree, boolean assumeDeterministic, boolean assumePureGetters) Compute whether the given statements, taken together, are side-effect-free, deterministic, or both.static @Nullable TypeMirrorReturnstype, or its upper bound if it is a type variable, if that is a functional interface type; otherwise returns null.static EnumSet<PurityKind> functionalParameterCallPurity(AnnotationProvider annoProvider, @Nullable ExpressionTree expr, ExecutableElement invoked, @Nullable MethodTree method, ProcessingEnvironment env) Returns the purity that a call ofinvokedonexprmay be assumed to have beyondinvoked's own annotations, ifexpris an effectively final functional-interface parameter ofmethodandinvokedis the functional method ofexpr's type (or overrides it); otherwise returns an empty set.static EnumSet<PurityKind> functionalParameterKinds(AnnotationProvider annoProvider, @Nullable ExecutableElement method, ProcessingEnvironment env) Returns the purity thatmethodrequires of every argument passed to one of its functional-interface parameters: the purity kinds ofmethod's own purity annotations, plus side-effect-freedom ifmethodhas or inherits@SideEffectsOnly.static EnumSet<PurityKind> functionalParameterPurity(AnnotationProvider annoProvider, ExecutableElement method, int index, ProcessingEnvironment env) Returns the purity that the argument passed tomethod's parameter atindexis known to have, beyond the annotations on the functional method of the parameter's type.static booleanisSameOrOverrides(ExecutableElement method, ExecutableElement other, ProcessingEnvironment env) Returns true ifmethodisotheror overrides it.static @Nullable ExecutableElementparameterFunctionalMethod(ExecutableElement method, int index, ProcessingEnvironment env) Returns the functional method of the type ofmethod's formal parameter atindex, or null if that parameter does not exist or does not hold code; seefunctionalMethodOfType(javax.lang.model.type.TypeMirror, javax.annotation.processing.ProcessingEnvironment).
-
Method Details
-
checkPurity
public static PurityChecker.PurityResult checkPurity(TreePath statement, AnnotationProvider annoProvider, @Nullable MethodTree enclosingMethod, @Nullable ProcessingEnvironment env, boolean assumeSideEffectFree, boolean assumeDeterministic, boolean assumePureGetters) Compute whether the given statement is side-effect-free, deterministic, or both. Returns a result that can be queried.- Parameters:
statement- the statement to checkannoProvider- the annotation providerenclosingMethod- the method declaration that lexically enclosesstatement, or null if none does. A call to the functional method of one of that method's functional-interface parameters has the purity that the method's callers required of the argument; seefunctionalParameterCallPurity(AnnotationProvider, ExpressionTree, ExecutableElement, MethodTree, ProcessingEnvironment). Pass the enclosing method for a lambda body too: the body is checked against the functional method that the lambda implements, but the enclosing method's parameters still hold values that its caller was required to check, whenever the lambda runs. Pass null for an arbitrary expression, which no method's contract governs.env- the processing environment; used only ifenclosingMethodis non-nullassumeSideEffectFree- true if all methods should be assumed to be @SideEffectFreeassumeDeterministic- true if all methods should be assumed to be @DeterministicassumePureGetters- true if all getter methods should be assumed to be @Pure- Returns:
- information about whether the given statement is side-effect-free, deterministic, or both
-
checkPurity
public static PurityChecker.PurityResult checkPurity(List<TreePath> statements, AnnotationProvider annoProvider, @Nullable MethodTree enclosingMethod, @Nullable ProcessingEnvironment env, boolean assumeSideEffectFree, boolean assumeDeterministic, boolean assumePureGetters) Compute whether the given statements, taken together, are side-effect-free, deterministic, or both. Returns a result that can be queried.Use this rather than calling
checkPurity(TreePath, AnnotationProvider, MethodTree, ProcessingEnvironment, boolean, boolean, boolean)once per statement, for code that runs as a unit but is not contiguous in the source code: a constructor together with the instance initializers that run as part of it, for example.- Parameters:
statements- the statements to checkannoProvider- the annotation providerenclosingMethod- the method declaration that lexically enclosesstatements, or null if none does; seecheckPurity(TreePath, AnnotationProvider, MethodTree, ProcessingEnvironment, boolean, boolean, boolean)env- the processing environment; used only ifenclosingMethodis non-nullassumeSideEffectFree- true if all methods should be assumed to be @SideEffectFreeassumeDeterministic- true if all methods should be assumed to be @DeterministicassumePureGetters- true if all getter methods should be assumed to be @Pure- Returns:
- information about whether the given statements are side-effect-free, deterministic, or both
-
functionalParameterKinds
public static EnumSet<PurityKind> functionalParameterKinds(AnnotationProvider annoProvider, @Nullable ExecutableElement method, ProcessingEnvironment env) Returns the purity thatmethodrequires of every argument passed to one of its functional-interface parameters: the purity kinds ofmethod's own purity annotations, plus side-effect-freedom ifmethodhas or inherits@SideEffectsOnly. The result is one set that applies to all ofmethod's functional-interface parameters alike. It depends only onmethod's annotations, not on which parameter is in question, nor on whether the body ever calls that parameter's functional method.Per-parameter computations refine this set. At a call to
method, an argument is not required to have a kind that the parameter's functional method already promises, nor to be deterministic if it is side-effect-free and returns no value. Within the body, a call to a parameter's functional method may assume the purity computed byfunctionalParameterPurity(org.checkerframework.javacutil.AnnotationProvider, javax.lang.model.element.ExecutableElement, int, javax.annotation.processing.ProcessingEnvironment), which also accounts for the methods thatmethodoverrides.A
@SideEffectsOnlymethod may modify the listed expressions, but each argument passed to one of its functional-interface parameters is required to be side-effect-free. A method inherits@SideEffectsOnlyfrom the methods that it overrides, though@SideEffectsOnlyis not inherited as an annotation.- Parameters:
annoProvider- the annotation providermethod- a method or constructor, or nullenv- the processing environment- Returns:
- the purity kinds that
methodrequires of every argument to one of its functional-interface parameters; empty ifmethodis null or has no purity annotation
-
functionalParameterCallPurity
public static EnumSet<PurityKind> functionalParameterCallPurity(AnnotationProvider annoProvider, @Nullable ExpressionTree expr, ExecutableElement invoked, @Nullable MethodTree method, ProcessingEnvironment env) Returns the purity that a call ofinvokedonexprmay be assumed to have beyondinvoked's own annotations, ifexpris an effectively final functional-interface parameter ofmethodandinvokedis the functional method ofexpr's type (or overrides it); otherwise returns an empty set. SeefunctionalParameterPurity(AnnotationProvider, ExecutableElement, int, ProcessingEnvironment).The code that such an expression denotes has the purity that
methodpromises, because at every call tomethodthe argument was required to have it. Only the functional method carries that guarantee; a default method such asFunction.andThendoes not.- Parameters:
annoProvider- the annotation providerexpr- an expression, or nullinvoked- a method thatexpris used to invoke or to refer tomethod- a method or constructor declaration, or nullenv- the processing environment- Returns:
- the purity that the call may be assumed to have, or an empty set
-
functionalParameterPurity
public static EnumSet<PurityKind> functionalParameterPurity(AnnotationProvider annoProvider, ExecutableElement method, int index, ProcessingEnvironment env) Returns the purity that the argument passed tomethod's parameter atindexis known to have, beyond the annotations on the functional method of the parameter's type. It is empty if that parameter's type is not a functional interface.A call reaches
methodthrough its own declaration or through any declaration that it overrides, and each call checks its arguments against the declaration that it invokes. The result is therefore the purity thatmethodpromises, less whatever any overridden declaration does not guarantee; seeguaranteedFunctionalArgumentPurity(org.checkerframework.javacutil.AnnotationProvider, javax.lang.model.element.ExecutableElement, int, javax.lang.model.element.ExecutableElement, javax.annotation.processing.ProcessingEnvironment). An overridden declaration with no purity annotation guarantees nothing, nor does one whose parameter atindexis not a functional interface, such as a type variable.- Parameters:
annoProvider- the annotation providermethod- a method or constructorindex- the index of one ofmethod's formal parametersenv- the processing environment- Returns:
- the purity that the argument at
indexis known to have
-
parameterFunctionalMethod
public static @Nullable ExecutableElement parameterFunctionalMethod(ExecutableElement method, int index, ProcessingEnvironment env) Returns the functional method of the type ofmethod's formal parameter atindex, or null if that parameter does not exist or does not hold code; seefunctionalMethodOfType(javax.lang.model.type.TypeMirror, javax.annotation.processing.ProcessingEnvironment). A varargs parameter's type is an array, which does not.- Parameters:
method- a method or constructorindex- the index of a formal parameterenv- the processing environment- Returns:
- the functional method of the parameter's type, or null
-
isSameOrOverrides
public static boolean isSameOrOverrides(ExecutableElement method, ExecutableElement other, ProcessingEnvironment env) Returns true ifmethodisotheror overrides it.- Parameters:
method- a methodother- another methodenv- the processing environment- Returns:
- true if
methodisotheror overrides it
-
functionalInterfaceType
public static @Nullable TypeMirror functionalInterfaceType(TypeMirror type, ProcessingEnvironment env) Returnstype, or its upper bound if it is a type variable, if that is a functional interface type; otherwise returns null. UseTypesUtils.findFunction(javax.lang.model.type.TypeMirror, javax.annotation.processing.ProcessingEnvironment)on the result to obtain the functional method.- Parameters:
type- a typeenv- the processing environment- Returns:
- the functional interface type that
typedenotes, or null
-