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, default annotations via DefaultFor
, 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.ParameterizedExecutableType
Modifier and Type | Field and Description |
---|---|
protected FlowAnalysis |
analysis |
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 DependentTypesHelper |
dependentTypesHelper
to handle dependent type annotations
|
protected Store |
emptyStore
An empty store.
|
protected IdentityHashMap<Tree,Store> |
exceptionalExitStores
A mapping from methods (or other code blocks) to their exceptional exit store.
|
protected static boolean |
flowByDefault
Should use flow by default.
|
protected AnalysisResult<Value,Store> |
flowResult
The result of the flow analysis.
|
protected Map<TransferInput<Value,Store>,IdentityHashMap<Node,TransferResult<Value,Store>>> |
flowResultAnalysisCaches
|
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
Map from ClassTree to their dataflow analysis state.
|
protected TransferFunction |
transfer |
protected TreeAnnotator |
treeAnnotator
to annotate types based on the given un-annotated types
|
protected TypeAnnotator |
typeAnnotator
to annotate types based on the given tree
|
artificialTreeToEnclosingElementMap, checker, elements, fromExpressionTreeCache, fromMemberTreeCache, fromTypeTreeCache, ignoreUninferredTypeArguments, loader, objectGetClass, processingEnv, qualHierarchy, qualifierUpperBounds, reflectionResolver, root, shouldCache, stubTypes, trees, typeArgumentInference, typeFormatter, typeHierarchy, types, typeVarSubstitutor, uid, visitorState
Modifier | Constructor and Description |
---|---|
protected |
GenericAnnotatedTypeFactory(BaseTypeChecker checker)
Creates a type factory for checking the given compilation unit with respect to the given
annotation.
|
protected |
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 |
addAnnotationsFromDefaultForType(@Nullable Element element,
AnnotatedTypeMirror type)
Adds default qualifiers bases on the underlying type of
type to type . |
protected void |
addCheckedCodeDefaults(QualifierDefaults defs)
Adds default qualifiers for type-checked code by reading
DefaultFor and DefaultQualifierInHierarchy meta-annotations. |
protected void |
addCheckedStandardDefaults(QualifierDefaults defs)
Adds the standard CLIMB defaults that do not conflict with previously added defaults.
|
void |
addComputedTypeAnnotations(Element elt,
AnnotatedTypeMirror type)
To add annotations to the type of method or constructor parameters, add a
TypeAnnotator using createTypeAnnotator() and see the comment in TypeAnnotator.visitExecutable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType,
Void) . |
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)
|
void |
addDefaultAnnotations(AnnotatedTypeMirror type)
Adds default annotations to
type . |
protected void |
addUncheckedStandardDefaults(QualifierDefaults defs)
Adds standard unchecked defaults that do not conflict with previously added defaults.
|
protected void |
analyze(Queue<Pair<ClassTree,Store>> queue,
Queue<Pair<LambdaExpressionTree,Store>> lambdaQueue,
UnderlyingAST ast,
List<Pair<VariableElement,Value>> fieldValues,
ClassTree currentClass,
boolean isInitializationCode,
boolean updateInitializationStore,
boolean isStatic,
Store capturedStore)
Analyze the AST
ast and store the result. |
protected void |
applyInferredAnnotations(AnnotatedTypeMirror type,
Value as)
Applies the annotations inferred by the org.checkerframework.dataflow analysis to the type
type . |
protected void |
applyQualifierParameterDefaults(@Nullable Element elt,
AnnotatedTypeMirror type)
Applies defaults for types in a class with an qualifier parameter.
|
protected void |
applyQualifierParameterDefaults(Tree tree,
AnnotatedTypeMirror type)
Applies defaults for types in a class with an qualifier parameter.
|
protected void |
checkAndPerformFlowAnalysis(Tree tree)
Flow analysis will be performed if all of the following are true.
|
protected void |
checkForDefaultQualifierInHierarchy(QualifierDefaults defs)
Check that a default qualifier (in at least one hierarchy) has been set and issue an error if
not.
|
AnnotatedTypeFactory.ParameterizedExecutableType |
constructorFromUse(NewClassTree tree)
Determines the type of the invoked constructor based on the passed new class tree.
|
protected void |
constructorFromUsePreSubstitution(NewClassTree tree,
AnnotatedTypeMirror.AnnotatedExecutableType type)
A callback method for the AnnotatedTypeFactory subtypes to customize the handling of the
declared constructor type before type variable substitution.
|
protected QualifierDefaults |
createAndInitQualifierDefaults()
Create
QualifierDefaults which handles checker specified defaults, and initialize the
created QualifierDefaults . |
protected CFGVisualizer<Value,Store,TransferFunction> |
createCFGVisualizer()
Create a new CFGVisualizer.
|
protected DefaultForTypeAnnotator |
createDefaultForTypeAnnotator()
Creates an
DefaultForTypeAnnotator . |
protected DefaultQualifierForUseTypeAnnotator |
createDefaultForUseTypeAnnotator()
Creates an
DefaultQualifierForUseTypeAnnotator . |
protected DependentTypesHelper |
createDependentTypesHelper()
Creates an
DependentTypesHelper and returns it. |
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 the
QualifierPolymorphism instance which supports the 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
DefaultForTypeAnnotator that adds annotations to a type based on the
content of the type itself. |
AnnotatedTypeMirror.AnnotatedDeclaredType |
fromNewClass(NewClassTree newClassTree)
Creates an AnnotatedDeclaredType for a NewClassTree.
|
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.
|
AnnotatedTypeMirror |
getAnnotatedTypeRhsUnaryAssign(UnaryTree tree) |
@Nullable AnnotatedTypeMirror |
getAnnotatedTypeVarargsArray(Tree tree)
Returns the type of a varargs array of a method invocation or a constructor invocation.
|
AnnotationMirror |
getAnnotationFromJavaExpressionString(String expression,
Tree tree,
TreePath path,
Class<? extends Annotation> clazz)
Returns the primary annotation on expression if it were evaluated at path.
|
AnnotationMirror |
getAnnotationFromReceiver(FlowExpressions.Receiver receiver,
Tree tree,
Class<? extends Annotation> clazz)
Returns the primary annotation on a receiver.
|
AnnotationMirror |
getAnnotationMirrorFromJavaExpressionString(String expression,
Tree tree,
TreePath currentPath)
Returns the annotation mirror from dataflow for
expression . |
CFGVisualizer<Value,Store,TransferFunction> |
getCFGVisualizer()
The CFGVisualizer to be used by all CFAbstractAnalysis instances.
|
DependentTypesHelper |
getDependentTypesHelper() |
Store |
getEmptyStore() |
Store |
getExceptionalExitStore(Tree tree)
Returns the exceptional exit store for a method or another code block (such as static
initializers).
|
HashMap<Element,Value> |
getFinalLocalValues()
Returns the value of effectively final local variables.
|
<T extends Node> |
getFirstNodeOfKindForTree(Tree tree,
Class<T> kind)
|
Value |
getInferredValueFor(Tree tree)
Returns the inferred value (by the org.checkerframework.dataflow analysis) for a given tree.
|
AnnotatedTypeMirror |
getMethodReturnType(MethodTree m)
Returns the return type of the method
m . |
AnnotatedTypeMirror |
getMethodReturnType(MethodTree m,
ReturnTree r)
Returns the return type of the method
m at the return statement r . |
Set<Node> |
getNodesForTree(Tree tree)
|
QualifierPolymorphism |
getQualifierPolymorphism()
Gives the current
QualifierPolymorphism instance which supports the
QualifierPolymorphism mechanism. |
Pair<FlowExpressions.Receiver,String> |
getReceiverAndOffsetFromJavaExpressionString(String expression,
TreePath currentPath)
Produces the receiver and offset associated with an expression.
|
FlowExpressions.Receiver |
getReceiverFromJavaExpressionString(String expression,
TreePath currentPath)
Produces the receiver associated with expression on currentPath.
|
Store |
getRegularExitStore(Tree tree)
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)
Returns a list of all return statements of
method paired with their corresponding
TransferResult . |
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(Node node)
Returns the store immediately after a given
Node . |
Store |
getStoreAfter(Set<Node> nodes)
Returns the store immediately after a given set of
Node s. |
Store |
getStoreAfter(Tree tree)
Returns the store immediately after a given
Tree . |
Store |
getStoreBefore(Node node)
Returns the store immediately before a given
Node . |
Store |
getStoreBefore(Set<Node> nodes)
Returns the store immediately before a given Set of
Node s. |
Store |
getStoreBefore(Tree tree)
Returns the store immediately before a given
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)
Returns the AnnotatedTypeFactory of the subchecker and copies the current visitor state to
the sub-factory so that the types are computed properly.
|
protected void |
handleCFGViz(ControlFlowGraph cfg)
Handle the visualization of the CFG, if necessary.
|
AnnotatedTypeFactory.ParameterizedExecutableType |
methodFromUse(MethodInvocationTree tree)
Determines the type of the invoked method based on the passed method invocation tree.
|
void |
methodFromUsePreSubstitution(ExpressionTree tree,
AnnotatedTypeMirror.AnnotatedExecutableType type)
A callback method for the AnnotatedTypeFactory subtypes to customize the handling of the
declared method type before type variable substitution.
|
protected void |
performFlowAnalysis(ClassTree classTree)
Perform a org.checkerframework.dataflow analysis over a single class tree and its nested
classes.
|
protected void |
postAnalyze(ControlFlowGraph cfg)
Perform any additional operations on a CFG.
|
void |
postAsMemberOf(AnnotatedTypeMirror type,
AnnotatedTypeMirror owner,
Element element)
A callback method for the AnnotatedTypeFactory subtypes to customize
AnnotatedTypes.asMemberOf().
|
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)
Performs flow-sensitive type refinement on
classTree if this type factory is
configured to do so. |
void |
setRoot(@Nullable CompilationUnitTree root)
Set the CompilationUnitTree that should be used.
|
List<AnnotatedTypeParameterBounds> |
typeVariablesFromUse(AnnotatedTypeMirror.AnnotatedDeclaredType type,
TypeElement element)
Adapt the upper bounds of the type variables of a class relative to the type instantiation.
|
adaptGetClassReturnTypeToReceiver, addAliasedAnnotation, addAliasedAnnotation, addAliasedAnnotation, addAliasedAnnotation, addAliasedDeclAnnotation, addAnnotationFromFieldInvariant, addInheritedAnnotation, applyUnboxing, areSameByClass, binaryTreeArgTypes, canonicalAnnotation, checkInvalidOptionsInferSignatures, containsSameByClass, createAnnotatedTypeFormatter, createAnnotationClassLoader, createAnnotationFormatter, createQualifierHierarchy, createQualifierHierarchyWithMultiGraphFactory, createQualifierUpperBounds, createSupportedTypeQualifiers, createTypeArgumentInference, createTypeHierarchy, createTypeVariableSubstitutor, declarationFromElement, fromElement, fromElement, fromElement, getAnnotatedNullType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedTypeFormatter, getAnnotatedTypeFromTypeTree, getAnnotationByClass, getAnnotationFormatter, getAnnotationMirror, getAnnotationWithMetaAnnotation, getBoxedType, getBundledTypeQualifiers, getCacheSize, getContext, getCurrentClassTree, getCurrentClassType, getCurrentMethodReceiver, getDeclAnnotation, getDeclAnnotationNoAliases, getDeclAnnotations, getDeclAnnotationWithMetaAnnotation, getDefaultTypeDeclarationBounds, getDummyAssignedTo, getElementUtils, getEnclosingClassOrMethod, getEnclosingElementForArtificialTree, getEnclosingType, getExpressionAndOffset, getFieldInvariantAnnotationTree, getFieldInvariantDeclarationAnnotations, getFieldInvariants, getFnInterfaceFromTree, getFunctionTypeFromTree, getFunctionTypeFromTree, getImplicitReceiverType, getNarrowedPrimitive, getPath, getProcessingEnv, getQualifierHierarchy, getQualifierParameterHierarchies, getQualifierParameterHierarchies, getQualifierUpperBounds, getReceiverType, getSelfType, getStringType, getSupportedTypeQualifierNames, getSupportedTypeQualifiers, getTreeUtils, getTypeArgumentInference, getTypeDeclarationBounds, getTypeHierarchy, getTypeOfExtendsImplements, getTypeVarSubstitutor, getUnboxedType, getUninferredWildcardType, getVisitorState, getWholeProgramInference, getWidenedAnnotations, getWidenedType, hasExplicitNoQualifierParameterInHierarchy, hasExplicitQualifierParameterInHierarchy, hasQualifierParameterInHierarchy, hasQualifierParameterInHierarchy, initializeReflectionResolution, isFromByteCode, isFromStubFile, isSupportedQualifier, isSupportedQualifier, isSupportedQualifier, isWithinConstructor, mergeStubsIntoType, methodFromUse, negateConstant, parseStubFiles, postProcessClassTree, postTypeVarSubstitution, setEnclosingElementForArtificialTree, shouldWarnIfStubRedundantWithBytecode, toAnnotatedType, toString, type, widenToUpperBound
protected static boolean flowByDefault
protected TypeAnnotator typeAnnotator
protected TreeAnnotator treeAnnotator
protected QualifierPolymorphism poly
protected QualifierDefaults defaults
protected DependentTypesHelper dependentTypesHelper
protected Store extends CFAbstractStore<Value,Store> emptyStore
protected FlowAnalysis extends CFAbstractAnalysis<Value,Store,TransferFunction> analysis
protected TransferFunction extends CFAbstractTransfer<Value,Store,TransferFunction> transfer
protected Store extends CFAbstractStore<Value,Store> initializationStore
protected Store extends CFAbstractStore<Value,Store> initializationStaticStore
protected final Map<TransferInput<Value extends CFAbstractValue<Value>,Store extends CFAbstractStore<Value,Store>>,IdentityHashMap<Node,TransferResult<Value extends CFAbstractValue<Value>,Store extends CFAbstractStore<Value,Store>>>> flowResultAnalysisCaches
AnalysisResult.runAnalysisFor(Node, boolean, TransferInput,
IdentityHashMap, Map)
. This cache is enabled if AnnotatedTypeFactory.shouldCache
is true. The cache size
is derived from AnnotatedTypeFactory.getCacheSize()
.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<Tree,Store extends CFAbstractStore<Value,Store>> exceptionalExitStores
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 CFGVisualizer<Value extends CFAbstractValue<Value>,Store extends CFAbstractStore<Value,Store>,TransferFunction extends CFAbstractTransfer<Value,Store,TransferFunction>> cfgVisualizer
protected GenericAnnotatedTypeFactory(BaseTypeChecker checker, boolean useFlow)
checker
- the checker to which this type factory belongsuseFlow
- whether flow analysis should be performedprotected 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 perform flow-sensitive type refinementpublic void setRoot(@Nullable CompilationUnitTree root)
AnnotatedTypeFactory
setRoot
in class AnnotatedTypeFactory
root
- the new compilation unit to usepublic final Set<Class<? extends Annotation>> getSupportedMonotonicTypeQualifiers()
MonotonicQualifier
protected TreeAnnotator createTreeAnnotator()
TreeAnnotator
that adds annotations to a type based on the contents of a
tree.
The default tree annotator is a ListTreeAnnotator
of the following:
PropagationTreeAnnotator
: Propagates annotations from subtrees
LiteralTreeAnnotator
: Adds annotations based on QualifierForLiterals
meta-annotations
DependentTypesTreeAnnotator
: Adapts dependent annotations based on context
Subclasses may override this method to specify additional tree annotators, for example:
new ListTreeAnnotator(super.createTreeAnnotator(), new KeyLookupTreeAnnotator(this));
protected TypeAnnotator createTypeAnnotator()
DefaultForTypeAnnotator
that adds annotations to a type based on the
content of the type itself.
Subclass may override this method. The default type annotator is a ListTypeAnnotator
of the following:
IrrelevantTypeAnnotator
: Adds top to types not listed in the RelevantJavaTypes
annotation on the checker.
PropagationTypeAnnotator
: Propagates annotation onto wildcards.
protected DefaultQualifierForUseTypeAnnotator createDefaultForUseTypeAnnotator()
DefaultQualifierForUseTypeAnnotator
.DefaultQualifierForUseTypeAnnotator
protected DefaultForTypeAnnotator createDefaultForTypeAnnotator()
DefaultForTypeAnnotator
.DefaultForTypeAnnotator
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 DependentTypesHelper createDependentTypesHelper()
DependentTypesHelper
and returns it.DependentTypesHelper
public DependentTypesHelper getDependentTypesHelper()
public AnnotatedTypeMirror.AnnotatedDeclaredType fromNewClass(NewClassTree newClassTree)
AnnotatedTypeFactory
Also, fully annotates the enclosing type of the returned declared type.
(Subclass beside GenericAnnotatedTypeFactory
should not override this method.)
fromNewClass
in class AnnotatedTypeFactory
newClassTree
- NewClassTreeprotected final QualifierDefaults createAndInitQualifierDefaults()
QualifierDefaults
which handles checker specified defaults, and initialize the
created QualifierDefaults
. Subclasses should override addCheckedCodeDefaults(QualifierDefaults defs)
to add more
defaults or use different defaults.protected QualifierDefaults createQualifierDefaults()
QualifierDefaults
which handles checker specified defaults. Sub-classes
override this method to provide a different QualifierDefault
implementation.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 addCheckedStandardDefaults(QualifierDefaults defs)
defs
- QualifierDefaults
object to which defaults are addedprotected void addUncheckedStandardDefaults(QualifierDefaults defs)
defs
- QualifierDefaults
object to which defaults are addedprotected void checkForDefaultQualifierInHierarchy(QualifierDefaults defs)
defs
- QualifierDefaults
object to which defaults are addedprotected QualifierPolymorphism createQualifierPolymorphism()
QualifierPolymorphism
instance which supports the QualifierPolymorphism
mechanism.public QualifierPolymorphism getQualifierPolymorphism()
QualifierPolymorphism
instance which supports the
QualifierPolymorphism mechanism.protected 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 AnnotationMirror getAnnotationFromJavaExpressionString(String expression, Tree tree, TreePath path, Class<? extends Annotation> clazz) throws FlowExpressionParseUtil.FlowExpressionParseException
expression
- a Java expressiontree
- current treepath
- location at which expression is evaluatedclazz
- class of the annotationFlowExpressionParseUtil.FlowExpressionParseException
- thrown if the expression cannot be parsedpublic AnnotationMirror getAnnotationFromReceiver(FlowExpressions.Receiver receiver, Tree tree, Class<? extends Annotation> clazz)
receiver
- the receiver for which the annotation is returnedtree
- current treeclazz
- the Class of the annotationpublic FlowExpressions.Receiver getReceiverFromJavaExpressionString(String expression, TreePath currentPath) throws FlowExpressionParseUtil.FlowExpressionParseException
expression
- a Java expressioncurrentPath
- location at which expression is evaluatedFlowExpressionParseUtil.FlowExpressionParseException
- thrown if the expression cannot be parsedpublic Pair<FlowExpressions.Receiver,String> getReceiverAndOffsetFromJavaExpressionString(String expression, TreePath currentPath) throws FlowExpressionParseUtil.FlowExpressionParseException
expression
- a Java expression, possibly with a constant offsetcurrentPath
- location at which expression is evaluatedFlowExpressionParseUtil.FlowExpressionParseException
- thrown if the expression cannot be parsedpublic AnnotationMirror getAnnotationMirrorFromJavaExpressionString(String expression, Tree tree, TreePath currentPath) throws FlowExpressionParseUtil.FlowExpressionParseException
expression
.
This will output a different annotation than getAnnotationFromJavaExpressionString(String, Tree, TreePath, Class)
, because if the
specified annotation isn't found in the store, the type from the factory is used.
expression
- a Java expressiontree
- the tree at the location to parse the expressioncurrentPath
- location at which expression is evaluatedFlowExpressionParseUtil.FlowExpressionParseException
- thrown if the expression cannot be parsedpublic Store getRegularExitStore(Tree tree)
tree
- a MethodTree or other code block, such as a static initializernull
, if there is no such store (because the
method cannot exit through the regular exit block).public Store getExceptionalExitStore(Tree tree)
tree
- a MethodTree or other code block, such as a static initializernull
, if there is no such store.public List<Pair<ReturnNode,TransferResult<Value,Store>>> getReturnStatementStores(MethodTree methodTree)
method
paired with their corresponding
TransferResult
. If method
has no return statement, then the empty list is
returned.methodTree
- method whose return statements should be returnedmethod
paired with their corresponding
TransferResult
or an empty list if method
has no return statementspublic Store getStoreBefore(Tree tree)
Tree
.Tree
public Store getStoreBefore(Set<Node> nodes)
Node
s.Node
spublic Store getStoreBefore(Node node)
Node
.Node
public Store getStoreAfter(Tree tree)
Tree
.Tree
public Store getStoreAfter(Set<Node> nodes)
Node
s.Node
spublic Store getStoreAfter(Node node)
Node
.node
- node after which the store is returnedNode
public Set<Node> getNodesForTree(Tree tree)
Node
s for a given Tree
AnalysisResult.getNodesForTree(Tree)
public <T extends Node> T getFirstNodeOfKindForTree(Tree tree, Class<T> kind)
Node
for a given Tree
that has class kind
.
You probably don't want to use this function: iterate over the result of getNodesForTree(Tree)
yourself or ask for a conservative approximation of the store using
getStoreBefore(Tree)
or getStoreAfter(Tree)
. This method is for code that
uses a Node
in a rather unusual way. Callers should probably be rewritten to not use
a Node
at all.
Node
for a given Tree
that of class kind
.getNodesForTree(Tree)
,
getStoreBefore(Tree)
,
getStoreAfter(Tree)
public HashMap<Element,Value> getFinalLocalValues()
protected void performFlowAnalysis(ClassTree classTree)
protected void analyze(Queue<Pair<ClassTree,Store>> queue, Queue<Pair<LambdaExpressionTree,Store>> lambdaQueue, UnderlyingAST ast, List<Pair<VariableElement,Value>> fieldValues, ClassTree currentClass, boolean isInitializationCode, boolean updateInitializationStore, boolean isStatic, Store capturedStore)
ast
and store the result. Additional operations that should be
performed after analysis should be implemented in postAnalyze(ControlFlowGraph)
.queue
- the queue for encountered class trees and their initial storeslambdaQueue
- the queue for encountered lambda expression trees and their initial storesast
- the AST to analyzefieldValues
- the abstract values for all fields of the same classcurrentClass
- the class we are currently looking atisInitializationCode
- are we analyzing a (static/non-static) initializer block of a
classupdateInitializationStore
- should the initialization store be updatedisStatic
- are we analyzing a static constructcapturedStore
- the input Store to use for captured variables, e.g. in a lambdapostAnalyze(org.checkerframework.dataflow.cfg.ControlFlowGraph)
protected void postAnalyze(ControlFlowGraph cfg)
analyze(Queue, Queue, UnderlyingAST, List, ClassTree, boolean, boolean,
boolean, CFAbstractStore)
. This method can be used to initialize additional state or to
perform any analyses that are easier to perform on the CFG instead of the AST.protected void handleCFGViz(ControlFlowGraph cfg)
cfg
- the CFGpublic AnnotatedTypeMirror getAnnotatedTypeLhsNoTypeVarDefault(Tree lhsTree)
The type variables that are types of local variables are defaulted to top so that they can
be refined by dataflow. When these types are used as context during type argument inference,
this default is too conservative. So this method is used instead of 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)
The default implementation returns the type without considering dataflow type refinement. Subclass can override this method and add additional logic for computing the type of a LHS.
lhsTree
- left-hand side of an assignmentlhsTree
public @Nullable AnnotatedTypeMirror getAnnotatedTypeVarargsArray(Tree tree)
useFlow
is false.tree
- a method invocation or a constructor invocationtree
; returns null if private field useFlow
is falsepublic AnnotatedTypeMirror getAnnotatedTypeRhsUnaryAssign(UnaryTree tree)
public AnnotatedTypeFactory.ParameterizedExecutableType 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(com.sun.source.tree.Tree, java.util.List<? extends org.checkerframework.framework.type.AnnotatedTypeParameterBounds>, java.util.List<? extends org.checkerframework.framework.type.AnnotatedTypeMirror>, java.util.List<? extends com.sun.source.tree.Tree>, javax.lang.model.element.Name, java.util.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 void constructorFromUsePreSubstitution(NewClassTree tree, AnnotatedTypeMirror.AnnotatedExecutableType type)
AnnotatedTypeFactory
constructorFromUsePreSubstitution
in class AnnotatedTypeFactory
tree
- a NewClassTree from constructorFromUse()type
- declared method type before type variable substitutionpublic AnnotatedTypeMirror getMethodReturnType(MethodTree m)
AnnotatedTypeFactory
m
.getMethodReturnType
in class AnnotatedTypeFactory
m
- a tree of methodpublic AnnotatedTypeMirror getMethodReturnType(MethodTree m, ReturnTree r)
AnnotatedTypeFactory
m
at the return statement r
.getMethodReturnType
in class AnnotatedTypeFactory
public void addDefaultAnnotations(AnnotatedTypeMirror type)
AnnotatedTypeFactory
type
. This method should only be used in places where the
correct annotations cannot be computed because of uninferred type arguments. (See AnnotatedTypeMirror.AnnotatedWildcardType.isUninferredTypeArgument()
.)addDefaultAnnotations
in class AnnotatedTypeFactory
type
- annotated type to which default annotations are addedprotected final void addComputedTypeAnnotations(Tree tree, AnnotatedTypeMirror type)
addComputedTypeAnnotations(Tree, AnnotatedTypeMirror,
boolean)
instead.
Changes annotations on a type obtained from a Tree
. By default, this method does
nothing. GenericAnnotatedTypeFactory uses this method to implement defaulting and inference
(flow-sensitive type refinement). Its subclasses usually override it only to customize
default annotations.
Subclasses that override this method should also override AnnotatedTypeFactory.addComputedTypeAnnotations(Element, AnnotatedTypeMirror)
.
In classes that extend GenericAnnotatedTypeFactory
, override addComputedTypeAnnotations(Tree, AnnotatedTypeMirror, boolean)
instead of this method.
addComputedTypeAnnotations
in class AnnotatedTypeFactory
tree
- an AST nodetype
- the type obtained from tree
protected void addComputedTypeAnnotations(Tree tree, AnnotatedTypeMirror type, boolean iUseFlow)
addComputedTypeAnnotations(Tree, AnnotatedTypeMirror)
. Overriding
implementations typically simply pass the boolean to calls to super.tree
- an AST nodetype
- the type obtained from treeiUseFlow
- whether to use information from dataflow analysisprotected 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
.protected void applyQualifierParameterDefaults(Tree tree, AnnotatedTypeMirror type)
Within a class with @HasQualifierParameter
, types with that class default to the
polymorphic qualifier rather than the typical default. Local variables with a type that has a
qualifier parameter are initialized to the type of their initializer, rather than the default
for local variables.
tree
- Tree whose type is type
type
- where the defaults are appliedprotected void applyQualifierParameterDefaults(@Nullable Element elt, AnnotatedTypeMirror type)
Within a class with @HasQualifierParameter
, types with that class default to the
polymorphic qualifier rather than the typical default. Local variables with a type that has a
qualifier parameter are initialized to the type of their initializer, rather than the default
for local variables.
elt
- Element whose type is type
type
- where the defaults are appliedpublic void addComputedTypeAnnotations(Element elt, AnnotatedTypeMirror type)
TypeAnnotator
using createTypeAnnotator()
and see the comment in TypeAnnotator.visitExecutable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType,
Void)
.addComputedTypeAnnotations
in class AnnotatedTypeFactory
elt
- an elementtype
- the type obtained from elt
public AnnotatedTypeFactory.ParameterizedExecutableType 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(com.sun.source.tree.Tree, java.util.List<? extends org.checkerframework.framework.type.AnnotatedTypeParameterBounds>, java.util.List<? extends org.checkerframework.framework.type.AnnotatedTypeMirror>, java.util.List<? extends com.sun.source.tree.Tree>, javax.lang.model.element.Name, java.util.List<?>)
for the checks of
type argument well-formedness.
Note that "this" and "super" constructor invocations are also handled by this method
(explicit or implicit ones, at the beginning of a constructor). Method AnnotatedTypeFactory.constructorFromUse(NewClassTree)
is only used for a constructor invocation in a "new"
expression.
methodFromUse
in class AnnotatedTypeFactory
tree
- the method invocation treepublic void methodFromUsePreSubstitution(ExpressionTree tree, AnnotatedTypeMirror.AnnotatedExecutableType type)
AnnotatedTypeFactory
methodFromUsePreSubstitution
in class AnnotatedTypeFactory
tree
- either a method invocation or a member reference treetype
- declared method type before type variable substitutionpublic List<AnnotatedTypeParameterBounds> typeVariablesFromUse(AnnotatedTypeMirror.AnnotatedDeclaredType type, TypeElement element)
AnnotatedTypeFactory
class C<X extends @Peer Object>
then the instantiation
@Rep C<@Rep Object>
is legal. The upper bounds of class C have to be adapted by the main modifier.
An example of an adaptation follows. Suppose, I have a declaration:
class MyClass<E extends List<E>>
And an instantiation:
new MyClass<@NonNull String>()
The upper bound of E adapted to the argument String, would be List<@NonNull
String>
and the lower bound would be an AnnotatedNullType.
TODO: ensure that this method is consistently used instead of directly querying the type variables.
typeVariablesFromUse
in class AnnotatedTypeFactory
type
- the use of the typeelement
- the corresponding elementpublic 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()
public void postAsMemberOf(AnnotatedTypeMirror type, AnnotatedTypeMirror owner, Element element)
AnnotatedTypeFactory
postAsMemberOf
in class AnnotatedTypeFactory
type
- the annotated type of the elementowner
- the annotated type of the receiver of the accessing treeelement
- the element of the field or methodprotected void addAnnotationsFromDefaultForType(@Nullable Element element, AnnotatedTypeMirror type)
type
to type
. If
element
is a local variable, then the defaults are not added.
(This uses both the DefaultQualifierForUseTypeAnnotator
and DefaultForTypeAnnotator
.)
element
- possibly null element whose type is type
type
- the type to which defaults are added