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
nullliteral, except when doing inference for the NullnessChecker. (The rationale for this is thatnullis a frequently-used default value, and it would be undesirable to infer the bottom type ifnullwere 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
FieldsModifier and TypeFieldDescriptionprotected final AnnotatedTypeFactoryThe type factory associated with this. -
Constructor Summary
ConstructorsConstructorDescriptionWholeProgramInferenceImplementation(AnnotatedTypeFactory atypeFactory, WholeProgramInferenceStorage<T> storage, boolean showWpiFailedInferences) Constructs a newWholeProgramInferenceImplementationthat has not yet inferred any annotations. -
Method Summary
Modifier and TypeMethodDescriptionvoidaddClassDeclarationAnnotation(TypeElement classElt, AnnotationMirror anno) Adds an annotation to a class declaration.voidaddDeclarationAnnotationToFormalParameter(ExecutableElement methodElt, @org.checkerframework.checker.index.qual.Positive int index_1based, AnnotationMirror anno) Adds a declaration annotation to a formal parameter.voidaddFieldDeclarationAnnotation(VariableElement field, AnnotationMirror anno) Updates a field to add a declaration annotation.voidaddMethodDeclarationAnnotation(ExecutableElement methodElt, AnnotationMirror anno) Updates a method to add a declaration annotation.voidaddMethodDeclarationAnnotation(ExecutableElement methodElt, AnnotationMirror anno, boolean lubPurity) Updates a method to add a declaration annotation.Returns the storage for inferred annotations.protected booleanignoreFieldInWPI(Element element, String fieldName) Returns true if an assignment to the given field should be ignored by WPI.voidpreprocessClassTree(ClassTree classTree) Performs any preparation required for inference on Elements of a class.protected voidupdateAnnotationSet(T annotationsToUpdate, TypeUseLocation defLoc, AnnotatedTypeMirror rhsATM, AnnotatedTypeMirror lhsATM, String file) Updates the set of annotations in a location in a program.protected voidupdateAnnotationSet(T annotationsToUpdate, TypeUseLocation defLoc, AnnotatedTypeMirror rhsATM, AnnotatedTypeMirror lhsATM, String file, boolean ignoreIfAnnotated) Updates the set of annotations in a location in a program.voidupdateAtmWithLub(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.voidupdateContracts(String className, Analysis.BeforeOrAfter preOrPost, ExecutableElement methodElt, CFAbstractStore<?, ?> store) Updates the preconditions or postconditions of the current method, from a store.voidupdateFieldFromType(Tree lhsTree, Element element, String fieldName, AnnotatedTypeMirror rhsATM) Updates the type offieldbased on an assignment whose right-hand side has typerhsATM.voidupdateFromFieldAssignment(Node lhs, Node rhs) Updates the type offieldbased on an assignment ofrhstofield.voidupdateFromFormalParameterAssignment(LocalVariableNode lhs, Node rhs, VariableElement paramElt) Updates the type oflhsbased on an assignment ofrhstolhs.voidupdateFromMethodInvocation(MethodInvocationNode methodInvNode, ExecutableElement methodElt, CFAbstractStore<?, ?> store) Updates the parameter types of the methodmethodEltbased on the arguments in the method invocationmethodInvNode.voidupdateFromObjectCreation(String className, ObjectCreationNode objectCreationNode, ExecutableElement constructorElt, CFAbstractStore<?, ?> store) Updates the parameter types of the constructorconstructorEltbased on the arguments inobjectCreationNode.voidupdateFromOverride(MethodTree methodTree, ExecutableElement methodElt, AnnotatedTypeMirror.AnnotatedExecutableType overriddenMethod) Updates the parameter types (including the receiver) of the methodmethodTreebased on the parameter types of the overridden methodoverriddenMethod.voidupdateFromReturn(ReturnNode retNode, com.sun.tools.javac.code.Symbol.ClassSymbol classSymbol, MethodTree methodDeclTree, Map<AnnotatedTypeMirror.AnnotatedDeclaredType, ExecutableElement> overriddenMethods) Updates the return type of the methodmethodTreebased onreturnedExpression.voidwriteResultsToFile(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 newWholeProgramInferenceImplementationthat has not yet inferred any annotations.- Parameters:
atypeFactory- the associated type factorystorage- the storage used for inferred annotations and for writing output filesshowWpiFailedInferences- true if the-AshowWpiFailedInferencesargument 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(String className, ObjectCreationNode objectCreationNode, ExecutableElement constructorElt, CFAbstractStore<?, ?> store) Description copied from interface:WholeProgramInferenceUpdates the parameter types of the constructorconstructorEltbased 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:
updateFromObjectCreationin interfaceWholeProgramInference- Parameters:
className- the class that contains the method, for diagnostics onlyobjectCreationNode- 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:WholeProgramInferenceUpdates the parameter types of the methodmethodEltbased 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:
updateFromMethodInvocationin 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(String className, Analysis.BeforeOrAfter preOrPost, ExecutableElement methodElt, CFAbstractStore<?, ?> store) Description copied from interface:WholeProgramInferenceUpdates the preconditions or postconditions of the current method, from a store.- Specified by:
updateContractsin interfaceWholeProgramInference- Parameters:
className- the name of the class, for debugging onlypreOrPost- true if 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:WholeProgramInferenceUpdates the parameter types (including the receiver) of the methodmethodTreebased 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:
updateFromOverridein 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:WholeProgramInferenceUpdates the type oflhsbased on an assignment ofrhstolhs.- 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:
updateFromFormalParameterAssignmentin 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:WholeProgramInferenceUpdates the type offieldbased on an assignment ofrhstofield. If the field has a declaration annotation with theIgnoreInWholeProgramInferencemeta-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:
updateFromFieldAssignmentin 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:WholeProgramInferenceUpdates the type offieldbased 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:
updateFieldFromTypein 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:WholeProgramInferenceUpdates the return type of the methodmethodTreebased 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:
updateFromReturnin 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:WholeProgramInferenceUpdates a method to add a declaration annotation.- Specified by:
addMethodDeclarationAnnotationin 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:WholeProgramInferenceUpdates a method to add a declaration annotation. Optionally, may replace the current purity annotation oneltwith the logical least upper bound between that purity annotation andanno, ifannois also a purity annotation.- Specified by:
addMethodDeclarationAnnotationin interfaceWholeProgramInference- Parameters:
methodElt- the method to annotateanno- the declaration annotation to add to the methodlubPurity- if true andannois a purity annotation, replaces the current purity annotation with a least upper bound rather than just addinganno
-
addFieldDeclarationAnnotation
Description copied from interface:WholeProgramInferenceUpdates a field to add a declaration annotation.- Specified by:
addFieldDeclarationAnnotationin 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:WholeProgramInferenceAdds a declaration annotation to a formal parameter.- Specified by:
addDeclarationAnnotationToFormalParameterin 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:WholeProgramInferenceAdds an annotation to a class declaration.- Specified by:
addClassDeclarationAnnotationin 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:WholeProgramInferenceUpdates 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:
updateAtmWithLubin 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:WholeProgramInferenceWrites 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:
writeResultsToFilein 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:WholeProgramInferencePerforms 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:
preprocessClassTreein interfaceWholeProgramInference- Parameters:
classTree- the class to preprocess
-