public abstract class GenericAnnotatedTypeFactory<Value extends CFAbstractValue<Value>,Store extends CFAbstractStore<Value,Store>,TransferFunction extends CFAbstractTransfer<Value,Store,TransferFunction>,FlowAnalysis extends CFAbstractAnalysis<Value,Store,TransferFunction>> extends AnnotatedTypeFactory
AnnotatedTypeFactory
to optionally use
flow-sensitive qualifier inference, qualifier polymorphism, implicit
annotations via ImplicitFor
, and user-specified defaults via
DefaultQualifier
.Modifier and Type | Class and Description |
---|---|
protected static class |
GenericAnnotatedTypeFactory.ScanState
Track the state of org.checkerframework.dataflow analysis scanning for each class tree in the
compilation unit.
|
AnnotatedTypeFactory.InheritedFromClassAnnotator
Modifier and Type | Field and Description |
---|---|
protected Deque<FlowAnalysis> |
analyses |
protected CFGVisualizer<Value,Store,TransferFunction> |
cfgVisualizer
The CFGVisualizer to be used by all CFAbstractAnalysis instances.
|
protected QualifierDefaults |
defaults
to handle defaults specified by the user
|
protected static boolean |
FLOW_BY_DEFAULT
should use flow by default
|
protected AnalysisResult<Value,Store> |
flowResult
The result of the flow analysis.
|
protected Store |
initializationStaticStore |
protected Store |
initializationStore |
protected IdentityHashMap<MethodInvocationTree,Store> |
methodInvocationStores
A mapping from methods to their a list with all return statements and the
corresponding store.
|
protected QualifierPolymorphism |
poly
to handle any polymorphic types
|
protected IdentityHashMap<Tree,Store> |
regularExitStores
A mapping from methods (or other code blocks) to their regular exit store (used to check
postconditions).
|
protected IdentityHashMap<MethodTree,List<Pair<ReturnNode,TransferResult<Value,Store>>>> |
returnStatementStores
A mapping from methods to a list with all return statements and the
corresponding store.
|
protected Map<ClassTree,GenericAnnotatedTypeFactory.ScanState> |
scannedClasses |
protected TreeAnnotator |
treeAnnotator
to annotate types based on the given un-annotated types
|
protected TypeAnnotator |
typeAnnotator
to annotate types based on the given tree
|
checker, elements, fromTreeCache, loader, processingEnv, qualHierarchy, reflectionResolver, root, shouldCache, trees, typeArgumentInference, typeFormatter, typeHierarchy, types, typeVarSubstitutor, uid, visitorState
Constructor and Description |
---|
GenericAnnotatedTypeFactory(BaseTypeChecker checker)
Creates a type factory for checking the given compilation unit with
respect to the given annotation.
|
GenericAnnotatedTypeFactory(BaseTypeChecker checker,
boolean useFlow)
Creates a type factory for checking the given compilation unit with
respect to the given annotation.
|
Modifier and Type | Method and Description |
---|---|
protected void |
addCheckedCodeDefaults(QualifierDefaults defs)
Adds default qualifiers for type-checked code by
reading
DefaultFor and DefaultQualifierInHierarchy
meta-annotations. |
void |
addComputedTypeAnnotations(Element elt,
AnnotatedTypeMirror type)
Adds implicit annotations to a type obtained from a
Element . |
protected void |
addComputedTypeAnnotations(Tree tree,
AnnotatedTypeMirror type)
This method is final; override
addComputedTypeAnnotations(Tree, AnnotatedTypeMirror, boolean)
instead. |
protected void |
addComputedTypeAnnotations(Tree tree,
AnnotatedTypeMirror type,
boolean iUseFlow)
Like {#addComputedTypeAnnotations(Tree, AnnotatedTypeMirror)}.
|
protected void |
addTypeNameImplicit(Class<?> clazz,
AnnotationMirror implicitAnno) |
protected void |
addUncheckedCodeDefaults(QualifierDefaults defs)
Adds default qualifiers for code that is not type-checked by
reading
@DefaultInUncheckedCodeFor and @DefaultQualifierInHierarchyInUncheckedCode
meta-annotations. |
protected void |
analyze(Queue<ClassTree> queue,
Queue<Pair<LambdaExpressionTree,Store>> lambdaQueue,
UnderlyingAST ast,
List<Pair<VariableElement,Value>> fieldValues,
ClassTree currentClass,
boolean isInitializationCode,
boolean updateInitializationStore,
boolean isStatic)
Analyze the AST
ast and store the result. |
protected void |
analyze(Queue<ClassTree> queue,
Queue<Pair<LambdaExpressionTree,Store>> lambdaQueue,
UnderlyingAST ast,
List<Pair<VariableElement,Value>> fieldValues,
ClassTree currentClass,
boolean isInitializationCode,
boolean updateInitializationStore,
boolean isStatic,
Store lambdaStore) |
protected void |
applyInferredAnnotations(AnnotatedTypeMirror type,
Value as)
Applies the annotations inferred by the org.checkerframework.dataflow analysis to the type
type . |
protected void |
checkAndPerformFlowAnalysis(Tree tree)
Flow analysis will be performed if:
tree is a
ClassTree
Flow analysis has not already been performed on tree
|
Pair<AnnotatedTypeMirror.AnnotatedExecutableType,List<AnnotatedTypeMirror>> |
constructorFromUse(NewClassTree tree)
Determines the type of the invoked constructor based on the passed new
class tree.
|
protected CFGVisualizer<Value,Store,TransferFunction> |
createCFGVisualizer() |
protected FlowAnalysis |
createFlowAnalysis(List<Pair<VariableElement,Value>> fieldValues)
Returns the appropriate flow analysis class that is used for the org.checkerframework.dataflow
analysis.
|
TransferFunction |
createFlowTransferFunction(CFAbstractAnalysis<Value,Store,TransferFunction> analysis)
Returns the appropriate transfer function that is used for the org.checkerframework.dataflow
analysis.
|
protected QualifierDefaults |
createQualifierDefaults()
Create
QualifierDefaults which handles checker specified defaults. |
protected QualifierPolymorphism |
createQualifierPolymorphism()
Creates
QualifierPolymorphism which supports
QualifierPolymorphism mechanism |
protected TreeAnnotator |
createTreeAnnotator()
Returns a
TreeAnnotator that adds annotations to a type based
on the contents of a tree. |
protected TypeAnnotator |
createTypeAnnotator()
Returns a
ImplicitsTypeAnnotator
that adds annotations to a type based on the content of the type itself. |
AnnotatedTypeMirror |
getAnnotatedTypeLhs(Tree lhsTree)
Returns the type of a left-hand side of an assignment.
|
AnnotatedTypeMirror |
getAnnotatedTypeLhsNoTypeVarDefault(Tree lhsTree)
Returns the type of the left-hand side of an assignment without
applying local variable defaults to type variables.
|
CFGVisualizer<Value,Store,TransferFunction> |
getCFGVisualizer()
The CFGVisualizer to be used by all CFAbstractAnalysis instances.
|
Store |
getEmptyStore() |
HashMap<Element,Value> |
getFinalLocalValues() |
Value |
getInferredValueFor(Tree tree)
Returns the inferred value (by the org.checkerframework.dataflow analysis) for a given tree.
|
Node |
getNodeForTree(Tree tree) |
Store |
getRegularExitStore(Tree t)
Returns the regular exit store for a method or another code block (such as static initializers).
|
AnnotatedTypeMirror |
getResultingTypeOfConstructorMemberReference(MemberReferenceTree memberReferenceTree,
AnnotatedTypeMirror.AnnotatedExecutableType constructorType)
Gets the type of the resulting constructor call of a MemberReferenceTree.
|
List<Pair<ReturnNode,TransferResult<Value,Store>>> |
getReturnStatementStores(MethodTree methodTree) |
boolean |
getShouldDefaultTypeVarLocals()
Should the local variable default annotation be applied to type variables?
|
protected String |
getSortedQualifierNames()
Creates and returns a string containing the number of qualifiers and the
canonical class names of each qualifier that has been added to this
checker's supported qualifier set.
|
Store |
getStoreAfter(Tree tree) |
Store |
getStoreBefore(Node node) |
Store |
getStoreBefore(Tree tree) |
Set<Class<? extends Annotation>> |
getSupportedMonotonicTypeQualifiers()
Returns an immutable set of the monotonic type qualifiers supported by this
checker.
|
<T extends GenericAnnotatedTypeFactory<?,?,?,?>,U extends BaseTypeChecker> |
getTypeFactoryOfSubchecker(Class<U> checkerClass) |
protected void |
handleCFGViz()
Handle the visualization of the CFG, by calling
visualizeCFG
on the first analysis. |
Pair<AnnotatedTypeMirror.AnnotatedExecutableType,List<AnnotatedTypeMirror>> |
methodFromUse(MethodInvocationTree tree)
Determines the type of the invoked method based on the passed method
invocation tree.
|
protected void |
performFlowAnalysis(ClassTree classTree)
Perform a org.checkerframework.dataflow analysis over a single class tree and its nested
classes.
|
protected void |
postDirectSuperTypes(AnnotatedTypeMirror type,
List<? extends AnnotatedTypeMirror> supertypes)
A callback method for the AnnotatedTypeFactory subtypes to customize
directSuperTypes().
|
protected void |
postInit()
Actions that logically belong in the constructor, but need to run
after the subclass constructor has completed.
|
void |
preProcessClassTree(ClassTree classTree)
Preforms flow-sensitive type refinement on
classTree if this type factory is
configured to do so. |
void |
setRoot(@Nullable CompilationUnitTree root) |
adaptGetClassReturnTypeToReceiver, addAliasedAnnotation, addAliasedDeclAnnotation, addInheritedAnnotation, aliasedAnnotation, annotateInheritedFromClass, annotateInheritedFromClass, checkInvalidOptionsInferSignatures, createAnnotatedTypeFormatter, createAnnotationFormatter, createQualifierHierarchy, createQualifierHierarchy, createQualifierHierarchy, createQualifierHierarchyFactory, createSupportedTypeQualifiers, createTypeArgumentInference, createTypeHierarchy, createTypeVariableSubstitutor, declarationFromElement, fromElement, fromElement, fromElement, fromNewClass, getAnnotatedNullType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedTypeFromTypeTree, getAnnotationFormatter, getAnnotationMirror, getAnnotationWithMetaAnnotation, getBoxedType, getBundledTypeQualifiersWithoutPolyAll, getBundledTypeQualifiersWithPolyAll, getContext, getCurrentClassTree, getCurrentClassType, getCurrentMethodReceiver, getDeclAnnotation, getDeclAnnotationNoAliases, getDeclAnnotations, getDeclAnnotationWithMetaAnnotation, getElementUtils, getEnclosingMethod, getEnclosingType, getFnInterfaceFromTree, getFnInterfaceFromTree, getImplicitReceiverType, getMethodReturnType, getMethodReturnType, getNarrowedPrimitive, getPath, getProcessingEnv, getQualifierHierarchy, getReceiverType, getSelfType, getStringType, getSupportedTypeQualifiers, getTreeUtils, getTypeArgumentInference, getTypeHierarchy, getTypeVarSubstitutor, getUnboxedType, getUninferredWildcardType, getVisitorState, getWholeProgramInference, initilizeReflectionResolution, isAnyEnclosingThisDeref, isFromByteCode, isFromStubFile, isMostEnclosingThisDeref, isSupportedQualifier, isWithinConstructor, methodFromUse, parseStubFiles, postAsMemberOf, postProcessClassTree, postTypeVarSubstitution, setPathHack, toAnnotatedType, toString, type, typeVariablesFromUse, widenToUpperBound
protected static boolean FLOW_BY_DEFAULT
protected TypeAnnotator typeAnnotator
protected TreeAnnotator treeAnnotator
protected QualifierPolymorphism poly
protected QualifierDefaults defaults
protected final Map<ClassTree,GenericAnnotatedTypeFactory.ScanState> scannedClasses
protected AnalysisResult<Value extends CFAbstractValue<Value>,Store extends CFAbstractStore<Value,Store>> flowResult
scannedClasses.get(c) == FINISHED for some class c ⇒ flowResult != nullNote that flowResult contains analysis results for Trees from multiple classes which are produced by multiple calls to performFlowAnalysis.
protected IdentityHashMap<Tree,Store extends CFAbstractStore<Value,Store>> regularExitStores
protected IdentityHashMap<MethodTree,List<Pair<ReturnNode,TransferResult<Value extends CFAbstractValue<Value>,Store extends CFAbstractStore<Value,Store>>>>> returnStatementStores
protected IdentityHashMap<MethodInvocationTree,Store extends CFAbstractStore<Value,Store>> methodInvocationStores
protected final Deque<FlowAnalysis extends CFAbstractAnalysis<Value,Store,TransferFunction>> analyses
protected Store extends CFAbstractStore<Value,Store> initializationStore
protected Store extends CFAbstractStore<Value,Store> initializationStaticStore
protected final CFGVisualizer<Value extends CFAbstractValue<Value>,Store extends CFAbstractStore<Value,Store>,TransferFunction extends CFAbstractTransfer<Value,Store,TransferFunction>> cfgVisualizer
public GenericAnnotatedTypeFactory(BaseTypeChecker checker, boolean useFlow)
checker
- the checker to which this type factory belongsuseFlow
- whether flow analysis should be performedpublic GenericAnnotatedTypeFactory(BaseTypeChecker checker)
checker
- the checker to which this type factory belongsprotected void postInit()
AnnotatedTypeFactory
postInit
in class AnnotatedTypeFactory
public void preProcessClassTree(ClassTree classTree)
classTree
if this type factory is
configured to do so.preProcessClassTree
in class AnnotatedTypeFactory
classTree
- tree on which to preform flow-sensitive type refinementpublic void setRoot(@Nullable CompilationUnitTree root)
setRoot
in class AnnotatedTypeFactory
public final Set<Class<? extends Annotation>> getSupportedMonotonicTypeQualifiers()
MonotonicQualifier
protected TreeAnnotator createTreeAnnotator()
TreeAnnotator
that adds annotations to a type based
on the contents of a tree.
Subclasses may override this method to specify a more appropriate
TreeAnnotator
.protected TypeAnnotator createTypeAnnotator()
ImplicitsTypeAnnotator
that adds annotations to a type based on the content of the type itself.protected void addTypeNameImplicit(Class<?> clazz, AnnotationMirror implicitAnno)
protected FlowAnalysis createFlowAnalysis(List<Pair<VariableElement,Value>> fieldValues)
This implementation uses the checker naming convention to create the
appropriate analysis. If no transfer function is found, it returns an
instance of CFAnalysis
.
Subclasses have to override this method to create the appropriate analysis if they do not follow the checker naming convention.
public TransferFunction createFlowTransferFunction(CFAbstractAnalysis<Value,Store,TransferFunction> analysis)
This implementation uses the checker naming convention to create the
appropriate transfer function. If no transfer function is found, it
returns an instance of CFTransfer
.
Subclasses have to override this method to create the appropriate transfer function if they do not follow the checker naming convention.
protected final QualifierDefaults createQualifierDefaults()
QualifierDefaults
which handles checker specified defaults.
Subclasses should override addCheckedCodeDefaults(QualifierDefaults defs)
or addUncheckedCodeDefaults(QualifierDefaults defs)
to add more defaults or use different defaults.protected final String getSortedQualifierNames()
protected void addCheckedCodeDefaults(QualifierDefaults defs)
DefaultFor
and DefaultQualifierInHierarchy
meta-annotations.
Subclasses may override this method to add defaults that cannot be specified with
a DefaultFor
or DefaultQualifierInHierarchy
meta-annotations.defs
- QualifierDefault object to which defaults are addedprotected void addUncheckedCodeDefaults(QualifierDefaults defs)
@DefaultInUncheckedCodeFor
and @DefaultQualifierInHierarchyInUncheckedCode
meta-annotations. Then it applies the standard
unchecked code defaults, if a default was not specified for a particular location.
Standard unchecked code default are:
top: TypeUseLocation.RETURN,TypeUseLocation.FIELD,TypeUseLocation.UPPER_BOUND
bottom: TypeUseLocation.PARAMETER, TypeUseLocation.LOWER_BOUND
If @DefaultQualifierInHierarchyInUncheckedCode
code is not found or a default for
TypeUseLocation.Otherwise
is not used, the defaults for checked code will be applied to
locations without a default for unchecked code.
Subclasses may override this method to add defaults that cannot be specified with
a @DefaultInUncheckedCodeFor
or @DefaultQualifierInHierarchyInUncheckedCode
meta-annotations or to change the standard defaults.
defs
- QualifierDefaults
object to which defaults are addedprotected QualifierPolymorphism createQualifierPolymorphism()
QualifierPolymorphism
which supports
QualifierPolymorphism mechanismprotected void postDirectSuperTypes(AnnotatedTypeMirror type, List<? extends AnnotatedTypeMirror> supertypes)
AnnotatedTypeFactory
The default provided implementation adds type
annotations to
supertypes
. This allows the type
and its supertypes
to have the qualifiers.
postDirectSuperTypes
in class AnnotatedTypeFactory
type
- the type whose supertypes are desiredsupertypes
- the supertypes as specified by the base AnnotatedTypeFactorypublic AnnotatedTypeMirror getResultingTypeOfConstructorMemberReference(MemberReferenceTree memberReferenceTree, AnnotatedTypeMirror.AnnotatedExecutableType constructorType)
memberReferenceTree
- MemberReferenceTree where the member is a constructorconstructorType
- AnnotatedExecutableType of the declaration of the constructorpublic Store getRegularExitStore(Tree t)
null
, if there is no such
store (because the method cannot exit through the regular exit
block).public List<Pair<ReturnNode,TransferResult<Value,Store>>> getReturnStatementStores(MethodTree methodTree)
public Store getStoreBefore(Tree tree)
Tree
.public Store getStoreBefore(Node node)
Node
.public Store getStoreAfter(Tree tree)
Tree
.public HashMap<Element,Value> getFinalLocalValues()
protected void performFlowAnalysis(ClassTree classTree)
protected void analyze(Queue<ClassTree> queue, Queue<Pair<LambdaExpressionTree,Store>> lambdaQueue, UnderlyingAST ast, List<Pair<VariableElement,Value>> fieldValues, ClassTree currentClass, boolean isInitializationCode, boolean updateInitializationStore, boolean isStatic)
ast
and store the result.queue
- The queue to add more things to scan.fieldValues
- The abstract values for all fields of the same class.ast
- The AST to analyze.currentClass
- the class we are currently looking atisInitializationCode
- are we analyzing a (non-static) initializer block of a classprotected void analyze(Queue<ClassTree> queue, Queue<Pair<LambdaExpressionTree,Store>> lambdaQueue, UnderlyingAST ast, List<Pair<VariableElement,Value>> fieldValues, ClassTree currentClass, boolean isInitializationCode, boolean updateInitializationStore, boolean isStatic, Store lambdaStore)
protected void handleCFGViz()
visualizeCFG
on the first analysis. This method gets invoked in analyze
if
on of the visualization options is provided.public AnnotatedTypeMirror getAnnotatedTypeLhsNoTypeVarDefault(Tree lhsTree)
getAnnotatedTypeLhs(Tree)
.
TypeArgInferenceUtil.assignedToVariable(AnnotatedTypeFactory, Tree)
explains
why a different type is used.lhsTree
- left-hand side of an assignmentlhsTree
public AnnotatedTypeMirror getAnnotatedTypeLhs(Tree lhsTree)
lhsTree
- left-hand side of an assignmentlhsTree
public Pair<AnnotatedTypeMirror.AnnotatedExecutableType,List<AnnotatedTypeMirror>> constructorFromUse(NewClassTree tree)
AnnotatedTypeFactory
The returned method type has all type variables resolved, whether based on receiver type, passed type parameters if any, and constructor invocation parameter.
Subclasses may override this method to customize inference of types or qualifiers based on constructor invocation parameters.
As an implementation detail, this method depends on
AnnotatedTypes.asMemberOf(Types, AnnotatedTypeFactory, AnnotatedTypeMirror, Element)
,
and customization based on receiver type should be in accordance with its
specification.
The return type is a pair of the type of the invoked constructor and
the (inferred) type arguments.
Note that neither the explicitly passed nor the inferred type arguments
are guaranteed to be subtypes of the corresponding upper bounds.
See method
BaseTypeVisitor.checkTypeArguments(Tree, List, List, List)
for the checks of type argument well-formedness.
Note that "this" and "super" constructor invocations are handled by
method AnnotatedTypeFactory.methodFromUse(com.sun.source.tree.MethodInvocationTree)
. This method only handles constructor invocations
in a "new" expression.
constructorFromUse
in class AnnotatedTypeFactory
tree
- the constructor invocation treeprotected final void addComputedTypeAnnotations(Tree tree, AnnotatedTypeMirror type)
addComputedTypeAnnotations(Tree, AnnotatedTypeMirror, boolean)
instead.
Adds implicit annotations to a type obtained from a Tree
. By
default, this method does nothing. Subclasses should use this method to
implement implicit annotations specific to their type systems.addComputedTypeAnnotations
in class AnnotatedTypeFactory
tree
- an AST nodetype
- the type obtained from tree
protected void addComputedTypeAnnotations(Tree tree, AnnotatedTypeMirror type, boolean iUseFlow)
protected void checkAndPerformFlowAnalysis(Tree tree)
ClassTree
tree
- the tree to check and possibly perform flow analysis onpublic Value getInferredValueFor(Tree tree)
protected void applyInferredAnnotations(AnnotatedTypeMirror type, Value as)
type
.public void addComputedTypeAnnotations(Element elt, AnnotatedTypeMirror type)
AnnotatedTypeFactory
Element
. By
default, this method does nothing. Subclasses should use this method to
implement implicit annotations specific to their type systems.addComputedTypeAnnotations
in class AnnotatedTypeFactory
elt
- an elementtype
- the type obtained from elt
public Pair<AnnotatedTypeMirror.AnnotatedExecutableType,List<AnnotatedTypeMirror>> methodFromUse(MethodInvocationTree tree)
AnnotatedTypeFactory
The returned method type has all type variables resolved, whether based on receiver type, passed type parameters if any, and method invocation parameter.
Subclasses may override this method to customize inference of types or qualifiers based on method invocation parameters.
As an implementation detail, this method depends on
AnnotatedTypes.asMemberOf(Types, AnnotatedTypeFactory, AnnotatedTypeMirror, Element)
,
and customization based on receiver type should be in accordance to its
specification.
The return type is a pair of the type of the invoked method and
the (inferred) type arguments.
Note that neither the explicitly passed nor the inferred type arguments
are guaranteed to be subtypes of the corresponding upper bounds.
See method
BaseTypeVisitor.checkTypeArguments(Tree, List, List, List)
for the checks of type argument well-formedness.
Note that "this" and "super" constructor invocations are also handled by this
method. Method AnnotatedTypeFactory.constructorFromUse(NewClassTree)
is only used for a constructor
invocation in a "new" expression.
methodFromUse
in class AnnotatedTypeFactory
tree
- the method invocation treepublic Store getEmptyStore()
public <T extends GenericAnnotatedTypeFactory<?,?,?,?>,U extends BaseTypeChecker> T getTypeFactoryOfSubchecker(Class<U> checkerClass)
public boolean getShouldDefaultTypeVarLocals()
It is initialized to true if data flow is used by the checker. It is set to false when getting the assignment context for type argument inference.
getAnnotatedTypeLhsNoTypeVarDefault(com.sun.source.tree.Tree)
protected CFGVisualizer<Value,Store,TransferFunction> createCFGVisualizer()
public CFGVisualizer<Value,Store,TransferFunction> getCFGVisualizer()