Class WholeProgramInferenceImplementation<T>
- Type Parameters:
T
- the type used by the storage to store annotations
- All Implemented Interfaces:
WholeProgramInference
WholeProgramInference
. It uses an instance of
WholeProgramInferenceStorage
to store annotations and to create output files.
This class does not perform inference for an element if the element has explicit annotations.
That is, calling an update*
method on an explicitly annotated field, method return, or
method parameter has no effect.
In addition, whole program inference ignores inferred types in a few scenarios. When discovering a use, WPI ignores an inferred type if:
- The inferred type of an element that should be written into a file is a subtype of the upper bounds of this element's written type in the source code.
- The annotation annotates a
null
literal, except when doing inference for the NullnessChecker. (The rationale for this is thatnull
is a frequently-used default value, and it would be undesirable to infer the bottom type ifnull
were the only value passed as an argument.)
- The @Target annotation does not permit the annotation to be written at this location.
- The @RelevantJavaTypes annotation does not permit the annotation to be written at this location.
- The inferred annotation has the @InvisibleQualifier meta-annotation.
- The inferred annotation would be the same annotation applied via defaulting — that is, if omitting it has the same effect as writing it.
- See Also:
-
Nested Class Summary
Nested classes/interfaces inherited from interface org.checkerframework.common.wholeprograminference.WholeProgramInference
WholeProgramInference.OutputFormat
-
Field Summary
Modifier and TypeFieldDescriptionprotected final AnnotatedTypeFactory
The type factory associated with this. -
Constructor Summary
ConstructorDescriptionWholeProgramInferenceImplementation
(AnnotatedTypeFactory atypeFactory, WholeProgramInferenceStorage<T> storage, boolean showWpiFailedInferences) Constructs a newWholeProgramInferenceImplementation
that has not yet inferred any annotations. -
Method Summary
Modifier and TypeMethodDescriptionvoid
addClassDeclarationAnnotation
(TypeElement classElt, AnnotationMirror anno) Adds an annotation to a class declaration.void
addDeclarationAnnotationToFormalParameter
(ExecutableElement methodElt, @org.checkerframework.checker.index.qual.Positive int index_1based, AnnotationMirror anno) Adds a declaration annotation to a formal parameter.void
addFieldDeclarationAnnotation
(VariableElement field, AnnotationMirror anno) Updates a field to add a declaration annotation.void
addMethodDeclarationAnnotation
(ExecutableElement methodElt, AnnotationMirror anno) Updates a method to add a declaration annotation.void
addMethodDeclarationAnnotation
(ExecutableElement methodElt, AnnotationMirror anno, boolean lubPurity) Updates a method to add a declaration annotation.Returns the storage for inferred annotations.protected boolean
ignoreFieldInWPI
(Element element, String fieldName) Returns true if an assignment to the given field should be ignored by WPI.void
preprocessClassTree
(ClassTree classTree) Performs any preparation required for inference on Elements of a class.protected void
updateAnnotationSet
(T annotationsToUpdate, TypeUseLocation defLoc, AnnotatedTypeMirror rhsATM, AnnotatedTypeMirror lhsATM, String file) Updates the set of annotations in a location in a program.protected void
updateAnnotationSet
(T annotationsToUpdate, TypeUseLocation defLoc, AnnotatedTypeMirror rhsATM, AnnotatedTypeMirror lhsATM, String file, boolean ignoreIfAnnotated) Updates the set of annotations in a location in a program.void
updateAtmWithLub
(AnnotatedTypeMirror sourceCodeATM, AnnotatedTypeMirror ajavaATM) Updates sourceCodeATM to contain the LUB between sourceCodeATM and ajavaATM, ignoring missing AnnotationMirrors from ajavaATM -- it considers the LUB between an AnnotationMirror am and a missing AnnotationMirror to be am.void
updateContracts
(Analysis.BeforeOrAfter preOrPost, ExecutableElement methodElt, CFAbstractStore<?, ?> store) Updates the preconditions or postconditions of the current method, from a store.void
updateFieldFromType
(Tree lhsTree, Element element, String fieldName, AnnotatedTypeMirror rhsATM) Updates the type offield
based on an assignment whose right-hand side has typerhsATM
.void
updateFromFieldAssignment
(Node lhs, Node rhs) Updates the type offield
based on an assignment ofrhs
tofield
.void
updateFromFormalParameterAssignment
(LocalVariableNode lhs, Node rhs, VariableElement paramElt) Updates the type oflhs
based on an assignment ofrhs
tolhs
.void
updateFromMethodInvocation
(MethodInvocationNode methodInvNode, ExecutableElement methodElt, CFAbstractStore<?, ?> store) Updates the parameter types of the methodmethodElt
based on the arguments in the method invocationmethodInvNode
.void
updateFromObjectCreation
(ObjectCreationNode objectCreationNode, ExecutableElement constructorElt, CFAbstractStore<?, ?> store) Updates the parameter types of the constructorconstructorElt
based on the arguments inobjectCreationNode
.void
updateFromOverride
(MethodTree methodTree, ExecutableElement methodElt, AnnotatedTypeMirror.AnnotatedExecutableType overriddenMethod) Updates the parameter types (including the receiver) of the methodmethodTree
based on the parameter types of the overridden methodoverriddenMethod
.void
updateFromReturn
(ReturnNode retNode, com.sun.tools.javac.code.Symbol.ClassSymbol classSymbol, MethodTree methodDeclTree, Map<AnnotatedTypeMirror.AnnotatedDeclaredType, ExecutableElement> overriddenMethods) Updates the return type of the methodmethodTree
based onreturnedExpression
.void
writeResultsToFile
(WholeProgramInference.OutputFormat outputFormat, BaseTypeChecker checker) Writes the inferred results to a file.
-
Field Details
-
atypeFactory
The type factory associated with this.
-
-
Constructor Details
-
WholeProgramInferenceImplementation
public WholeProgramInferenceImplementation(AnnotatedTypeFactory atypeFactory, WholeProgramInferenceStorage<T> storage, boolean showWpiFailedInferences) Constructs a newWholeProgramInferenceImplementation
that has not yet inferred any annotations.- Parameters:
atypeFactory
- the associated type factorystorage
- the storage used for inferred annotations and for writing output filesshowWpiFailedInferences
- whether the-AshowWpiFailedInferences
argument was passed to the checker, and therefore whether to print debugging messages when inference fails
-
-
Method Details
-
getStorage
Returns the storage for inferred annotations.- Returns:
- the storage for the inferred annotations
-
updateFromObjectCreation
public void updateFromObjectCreation(ObjectCreationNode objectCreationNode, ExecutableElement constructorElt, CFAbstractStore<?, ?> store) Description copied from interface:WholeProgramInference
Updates the parameter types of the constructorconstructorElt
based on the arguments inobjectCreationNode
.For each parameter in constructorElt:
- If there is no stored annotated type for that parameter, then use the type of the corresponding argument in the object creation call objectCreationNode.
- If there was a stored annotated type for that parameter, then its new type will be the LUB between the previous type and the type of the corresponding argument in the object creation call.
- Specified by:
updateFromObjectCreation
in interfaceWholeProgramInference
- Parameters:
objectCreationNode
- the Node that invokes the constructorconstructorElt
- the Element of the constructorstore
- the store just before the call
-
updateFromMethodInvocation
public void updateFromMethodInvocation(MethodInvocationNode methodInvNode, ExecutableElement methodElt, CFAbstractStore<?, ?> store) Description copied from interface:WholeProgramInference
Updates the parameter types of the methodmethodElt
based on the arguments in the method invocationmethodInvNode
.For each formal parameter in methodElt (including the receiver):
- If there is no stored annotated type for that parameter, then use the type of the corresponding argument in the method call methodInvNode.
- If there was a stored annotated type for that parameter, then its new type will be the LUB between the previous type and the type of the corresponding argument in the method call.
- Specified by:
updateFromMethodInvocation
in interfaceWholeProgramInference
- Parameters:
methodInvNode
- the node representing a method invocationmethodElt
- the element of the method being invokedstore
- the store before the method call, used for inferring method preconditions
-
updateContracts
public void updateContracts(Analysis.BeforeOrAfter preOrPost, ExecutableElement methodElt, CFAbstractStore<?, ?> store) Description copied from interface:WholeProgramInference
Updates the preconditions or postconditions of the current method, from a store.- Specified by:
updateContracts
in interfaceWholeProgramInference
- Parameters:
preOrPost
- whether to update preconditions or postconditionsmethodElt
- the method or constructor whose preconditions or postconditions to updatestore
- the store at the method's entry or normal exit, for reading types of expressions
-
updateFromOverride
public void updateFromOverride(MethodTree methodTree, ExecutableElement methodElt, AnnotatedTypeMirror.AnnotatedExecutableType overriddenMethod) Description copied from interface:WholeProgramInference
Updates the parameter types (including the receiver) of the methodmethodTree
based on the parameter types of the overridden methodoverriddenMethod
.For each formal parameter in methodElt:
- If there is no stored annotated type for that parameter, then use the type of the corresponding parameter on the overridden method.
- If there is a stored annotated type for that parameter, then its new type will be the LUB between the previous type and the type of the corresponding parameter on the overridden method.
- Specified by:
updateFromOverride
in interfaceWholeProgramInference
- Parameters:
methodTree
- the tree of the method that contains the parameter(s)methodElt
- the element of the methodoverriddenMethod
- the AnnotatedExecutableType of the overridden method
-
updateFromFormalParameterAssignment
public void updateFromFormalParameterAssignment(LocalVariableNode lhs, Node rhs, VariableElement paramElt) Description copied from interface:WholeProgramInference
Updates the type oflhs
based on an assignment ofrhs
tolhs
.- If there is no stored annotated type for lhs, then use the type of the corresponding argument in the method call methodInvNode.
- If there is a stored annotated type for lhs, then its new type will be the LUB between the previous type and the type of the corresponding argument in the method call.
- Specified by:
updateFromFormalParameterAssignment
in interfaceWholeProgramInference
- Parameters:
lhs
- the node representing the formal parameterrhs
- the node being assigned to the parameter in the method bodyparamElt
- the formal parameter
-
updateFromFieldAssignment
Description copied from interface:WholeProgramInference
Updates the type offield
based on an assignment ofrhs
tofield
. If the field has a declaration annotation with theIgnoreInWholeProgramInference
meta-annotation, no type annotation will be inferred for that field.If there is no stored entry for the field lhs, the entry will be created and its type will be the type of rhs. If there is a stored entry/type for lhs, its new type will be the LUB between the previous type and the type of rhs.
- Specified by:
updateFromFieldAssignment
in interfaceWholeProgramInference
- Parameters:
lhs
- the field whose type will be refined. Must be either a FieldAccessNode or a LocalVariableNode whose element kind is FIELD.rhs
- the expression being assigned to the field
-
updateFieldFromType
public void updateFieldFromType(Tree lhsTree, Element element, String fieldName, AnnotatedTypeMirror rhsATM) Description copied from interface:WholeProgramInference
Updates the type offield
based on an assignment whose right-hand side has typerhsATM
. See more details atWholeProgramInference.updateFromFieldAssignment(org.checkerframework.dataflow.cfg.node.Node, org.checkerframework.dataflow.cfg.node.Node)
.- Specified by:
updateFieldFromType
in interfaceWholeProgramInference
- Parameters:
lhsTree
- the tree for the field whose type will be refinedelement
- the element for the field whose type will be refinedfieldName
- the name of the field whose type will be refinedrhsATM
- the type of the expression being assigned to the field
-
ignoreFieldInWPI
Returns true if an assignment to the given field should be ignored by WPI.- Parameters:
element
- the field's elementfieldName
- the field's name- Returns:
- true if an assignment to the given field should be ignored by WPI
-
updateFromReturn
public void updateFromReturn(ReturnNode retNode, com.sun.tools.javac.code.Symbol.ClassSymbol classSymbol, MethodTree methodDeclTree, Map<AnnotatedTypeMirror.AnnotatedDeclaredType, ExecutableElement> overriddenMethods) Description copied from interface:WholeProgramInference
Updates the return type of the methodmethodTree
based onreturnedExpression
. Also updates the return types of any methods that this method overrides that are available as source code.If there is no stored annotated return type for the method methodTree, then the type of the return expression will be added to the return type of that method. If there is a stored annotated return type for the method methodTree, its new type will be the LUB between the previous type and the type of the return expression.
- Specified by:
updateFromReturn
in interfaceWholeProgramInference
- Parameters:
retNode
- the node that contains the expression returnedclassSymbol
- the symbol of the class that contains the methodmethodDeclTree
- the tree of the method whose return type may be updatedoverriddenMethods
- the methods that the given method return overrides, indexed by the annotated type of the superclass in which each method is defined
-
addMethodDeclarationAnnotation
Description copied from interface:WholeProgramInference
Updates a method to add a declaration annotation.- Specified by:
addMethodDeclarationAnnotation
in interfaceWholeProgramInference
- Parameters:
methodElt
- the method to annotateanno
- the declaration annotation to add to the method
-
addMethodDeclarationAnnotation
public void addMethodDeclarationAnnotation(ExecutableElement methodElt, AnnotationMirror anno, boolean lubPurity) Description copied from interface:WholeProgramInference
Updates a method to add a declaration annotation. Optionally, may replace the current purity annotation onelt
with the logical least upper bound between that purity annotation andanno
, ifanno
is also a purity annotation.- Specified by:
addMethodDeclarationAnnotation
in interfaceWholeProgramInference
- Parameters:
methodElt
- the method to annotateanno
- the declaration annotation to add to the methodlubPurity
- if true andanno
is a purity annotation, replaces the current purity annotation with a least upper bound rather than just addinganno
-
addFieldDeclarationAnnotation
Description copied from interface:WholeProgramInference
Updates a field to add a declaration annotation.- Specified by:
addFieldDeclarationAnnotation
in interfaceWholeProgramInference
- Parameters:
field
- the field to annotateanno
- the declaration annotation to add to the field
-
addDeclarationAnnotationToFormalParameter
public void addDeclarationAnnotationToFormalParameter(ExecutableElement methodElt, @org.checkerframework.checker.index.qual.Positive int index_1based, AnnotationMirror anno) Description copied from interface:WholeProgramInference
Adds a declaration annotation to a formal parameter.- Specified by:
addDeclarationAnnotationToFormalParameter
in interfaceWholeProgramInference
- Parameters:
methodElt
- the method whose formal parameter will be annotatedindex_1based
- the index of the parameter (1-indexed)anno
- the annotation to add
-
addClassDeclarationAnnotation
Description copied from interface:WholeProgramInference
Adds an annotation to a class declaration.- Specified by:
addClassDeclarationAnnotation
in interfaceWholeProgramInference
- Parameters:
classElt
- the class declaration to annotateanno
- the annotation to add
-
updateAnnotationSet
protected void updateAnnotationSet(T annotationsToUpdate, TypeUseLocation defLoc, AnnotatedTypeMirror rhsATM, AnnotatedTypeMirror lhsATM, String file) Updates the set of annotations in a location in a program.- If there was no previous annotation for that location, then the updated set will be the annotations in rhsATM.
- If there was a previous annotation, the updated set will be the LUB between the previous annotation and rhsATM.
Subclasses can customize this behavior.
- Parameters:
annotationsToUpdate
- the type whose annotations are modified by this methoddefLoc
- the location where the annotation will be addedrhsATM
- the RHS of the annotated type on the source codelhsATM
- the LHS of the annotated type on the source codefile
- the annotation file containing the executable; used for marking the scene as modified (needing to be written to disk)
-
updateAnnotationSet
protected void updateAnnotationSet(T annotationsToUpdate, TypeUseLocation defLoc, AnnotatedTypeMirror rhsATM, AnnotatedTypeMirror lhsATM, String file, boolean ignoreIfAnnotated) Updates the set of annotations in a location in a program.- If there was no previous annotation for that location, then the updated set will be the annotations in rhsATM.
- If there was a previous annotation, the updated set will be the LUB between the previous annotation and rhsATM.
Subclasses can customize this behavior.
- Parameters:
annotationsToUpdate
- the type whose annotations are modified by this methoddefLoc
- the location where the annotation will be addedrhsATM
- the RHS of the annotated type on the source codelhsATM
- the LHS of the annotated type on the source codefile
- annotation file containing the executable; used for marking the scene as modified (needing to be written to disk)ignoreIfAnnotated
- if true, don't update any type that is explicitly annotated in the source code
-
updateAtmWithLub
Description copied from interface:WholeProgramInference
Updates sourceCodeATM to contain the LUB between sourceCodeATM and ajavaATM, ignoring missing AnnotationMirrors from ajavaATM -- it considers the LUB between an AnnotationMirror am and a missing AnnotationMirror to be am. The results are stored in sourceCodeATM.- Specified by:
updateAtmWithLub
in interfaceWholeProgramInference
- Parameters:
sourceCodeATM
- the annotated type on the source code; side effected by this methodajavaATM
- the annotated type on the annotation file
-
writeResultsToFile
public void writeResultsToFile(WholeProgramInference.OutputFormat outputFormat, BaseTypeChecker checker) Description copied from interface:WholeProgramInference
Writes the inferred results to a file. Ideally, it should be called at the end of the type-checking process. In practice, it is called after each class, because we don't know which class will be the last one in the type-checking process.- Specified by:
writeResultsToFile
in interfaceWholeProgramInference
- Parameters:
outputFormat
- the file format in which to write the resultschecker
- the checker from which this method is called, for naming annotation files
-
preprocessClassTree
Description copied from interface:WholeProgramInference
Performs any preparation required for inference on Elements of a class. Should be called on each toplevel class declaration in a compilation unit before processing it.- Specified by:
preprocessClassTree
in interfaceWholeProgramInference
- Parameters:
classTree
- the class to preprocess
-