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.
It also adds other features: qualifier polymorphism, default annotations via DefaultFor
, user-specified defaults via DefaultQualifier
, standardization via DependentTypesHelper
, etc. Those features, and addComputedTypeAnnotations(com.sun.source.tree.Tree, org.checkerframework.framework.type.AnnotatedTypeMirror)
(other than
the part related to flow-sensitivity), could and should be in the superclass AnnotatedTypeFactory
; it is not clear why they are defined in this class.
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 ContractsFromMethod |
contractsUtils
to handle method pre- and postconditions
|
protected QualifierDefaults |
defaults
to handle defaults specified by the user
|
protected DependentTypesHelper |
dependentTypesHelper
To handle dependent type annotations and contract expressions.
|
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 static Pattern |
formalParameterPattern
Matches parameter expressions as they appear in
EnsuresQualifier and RequiresQualifier annotations, e.g. |
boolean |
hasOrIsSubchecker
True if this checker either has one or more subcheckers, or if this checker is a subchecker.
|
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).
|
@Nullable Set<TypeMirror> |
relevantJavaTypes
The Java types on which users may write this type system's type annotations.
|
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 boolean |
shouldClearSubcheckerSharedCFGs
If true,
setRoot(CompilationUnitTree) should clear the subcheckerSharedCFG
map, freeing memory. |
boolean |
sideEffectsUnrefineAliases
Should the analysis assume that side effects to a value can change the type of aliased
references?
|
protected @Nullable Map<Tree,ControlFlowGraph> |
subcheckerSharedCFG
Subcheckers share the same ControlFlowGraph for each analyzed code statement.
|
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
|
ajavaTypes, artificialTreeToEnclosingElementMap, checker, currentFileAjavaTypes, elements, fromExpressionTreeCache, fromMemberTreeCache, fromTypeTreeCache, ignoreUninferredTypeArguments, loader, methodValClassNameElement, methodValMethodNameElement, methodValParamsElement, objectGetClass, processingEnv, qualHierarchy, qualifierUpperBounds, reflectionResolver, root, shouldCache, stubTypes, trees, typeArgumentInference, typeFormatter, typeHierarchy, types, typeVarSubstitutor, uid, wpiOutputFormat
Modifier | Constructor and Description |
---|---|
protected |
GenericAnnotatedTypeFactory(BaseTypeChecker checker)
Creates a type factory.
|
protected |
GenericAnnotatedTypeFactory(BaseTypeChecker checker,
boolean useFlow)
Creates a type factory.
|
Modifier and Type | Method and Description |
---|---|
protected void |
addAnnotationsFromDefaultForType(@Nullable Element element,
AnnotatedTypeMirror type)
Adds default qualifiers based 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 . |
boolean |
addSharedCFGForTree(Tree tree,
ControlFlowGraph cfg)
Add a new entry to the shared CFG.
|
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<CFAbstractAnalysis.FieldInitialValue<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 @Nullable CFGVisualizer<Value,Store,TransferFunction> |
createCFGVisualizer()
Create a new CFGVisualizer.
|
protected ContractsFromMethod |
createContractsFromMethod()
Creates an
ContractsFromMethod and returns it. |
protected DefaultForTypeAnnotator |
createDefaultForTypeAnnotator()
Creates an
DefaultForTypeAnnotator . |
protected DefaultQualifierForUseTypeAnnotator |
createDefaultForUseTypeAnnotator()
Creates an
DefaultQualifierForUseTypeAnnotator . |
protected DependentTypesHelper |
createDependentTypesHelper()
Creates a
DependentTypesHelper and returns it. |
protected FlowAnalysis |
createFlowAnalysis()
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 @Nullable AnnotationMirror |
createRequiresOrEnsuresQualifier(String expression,
AnnotationMirror qualifier,
AnnotatedTypeMirror declaredType,
Analysis.BeforeOrAfter preOrPost,
@Nullable List<AnnotationMirror> preconds)
Creates a
RequiresQualifier("...") or EnsuresQualifier("...") annotation for
the given expression. |
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 |
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)
Returns the type of
v + 1 or v - 1 where v is the expression in the
postfixed increment or decrement expression. |
@Nullable AnnotatedTypeMirror |
getAnnotatedTypeVarargsArray(Tree tree)
Returns the type of a varargs array of a method invocation or a constructor invocation.
|
AnnotationMirror |
getAnnotationFromJavaExpression(JavaExpression expr,
Tree tree,
Class<? extends Annotation> clazz)
Returns the primary annotation on an expression, at a particular location.
|
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 |
getAnnotationMirrorFromJavaExpressionString(String expression,
Tree tree,
TreePath currentPath)
Returns the annotation mirror from dataflow for
expression . |
Set<AnnotationMirror> |
getAnnotationsFromJavaExpression(JavaExpression expr,
Tree tree)
Returns the primary annotations on an expression, at a particular location.
|
CFGVisualizer<Value,Store,TransferFunction> |
getCFGVisualizer()
The CFGVisualizer to be used by all CFAbstractAnalysis instances.
|
List<AnnotationMirror> |
getContractAnnotations(scenelib.annotations.el.AMethod m)
Return the contract annotations (that is, pre- and post-conditions) for the given AMethod.
|
List<AnnotationMirror> |
getContractAnnotations(WholeProgramInferenceJavaParserStorage.CallableDeclarationAnnos methodAnnos)
Return the contract annotations (that is, pre- and post-conditions) for the given
CallableDeclarationAnnos.
|
List<String> |
getContractExpressions(Contract.Kind kind,
AnnotationMirror contractAnnotation)
If
contractAnnotation is a framework annotation, return its expression element. |
ContractsFromMethod |
getContractsFromMethod()
Returns the helper for method pre- and postconditions.
|
DefaultForTypeAnnotator |
getDefaultForTypeAnnotator()
Returns the
DefaultForTypeAnnotator . |
AnnotatedTypeMirror |
getDefaultValueAnnotatedType(TypeMirror typeMirror)
Return the type of the default value of the given type.
|
DependentTypesHelper |
getDependentTypesHelper()
Returns the DependentTypesHelper.
|
Store |
getEmptyStore()
Returns the empty store.
|
Boolean |
getEnsuresQualifierIfResult(Contract.Kind kind,
AnnotationMirror contractAnnotation)
If kind = CONDITIONALPOSTCONDITION, return the result element, e.g.
|
Store |
getExceptionalExitStore(Tree tree)
Returns the exceptional exit store for a method or another code block (such as static
initializers).
|
Set<AnnotationMirror> |
getExplicitNewClassAnnos(NewClassTree newClassTree)
Returns the annotations explicitly written on a NewClassTree.
|
protected List<AnnotatedTypeMirror> |
getExplicitNewClassClassTypeArgs(NewClassTree newClassTree)
Returns the partially-annotated explicit class type arguments of the new class tree.
|
Pair<JavaExpression,String> |
getExpressionAndOffsetFromJavaExpressionString(String expression,
TreePath currentPath)
Produces the JavaExpression and offset associated with an expression.
|
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 . |
Set<Node> |
getNodesForTree(Tree tree)
|
List<AnnotationMirror> |
getPostconditionAnnotations(scenelib.annotations.el.AMethod m,
List<AnnotationMirror> preconds)
Return the postcondition annotations for the given AMethod.
|
List<AnnotationMirror> |
getPostconditionAnnotations(String expression,
AnnotatedTypeMirror inferredType,
AnnotatedTypeMirror declaredType,
List<AnnotationMirror> preconds)
Returns a list of inferred
@EnsuresQualifier annotations for the given expression. |
List<AnnotationMirror> |
getPostconditionAnnotations(WholeProgramInferenceJavaParserStorage.CallableDeclarationAnnos methodAnnos,
List<AnnotationMirror> preconds)
Return the postcondition annotations for the given CallableDeclarationAnnos.
|
List<AnnotationMirror> |
getPreconditionAnnotations(scenelib.annotations.el.AMethod m)
Return the precondition annotations for the given AMethod.
|
List<AnnotationMirror> |
getPreconditionAnnotations(String expression,
AnnotatedTypeMirror inferredType,
AnnotatedTypeMirror declaredType)
Returns a list of inferred
@RequiresQualifier annotations for the given expression. |
List<AnnotationMirror> |
getPreconditionAnnotations(WholeProgramInferenceJavaParserStorage.CallableDeclarationAnnos methodAnnos)
Return the precondition annotations for the given CallableDeclarationAnnos.
|
protected List<AnnotationMirror> |
getPreOrPostconditionAnnotations(String expression,
AnnotatedTypeMirror inferredType,
AnnotatedTypeMirror declaredType,
Analysis.BeforeOrAfter preOrPost,
@Nullable List<AnnotationMirror> preconds)
Creates pre- and postcondition annotations.
|
QualifierPolymorphism |
getQualifierPolymorphism()
Gives the current
QualifierPolymorphism instance which supports the
QualifierPolymorphism mechanism. |
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 . |
@Nullable ControlFlowGraph |
getSharedCFGForTree(Tree tree)
Get the shared control flow graph used for
tree by this checker's topmost superchecker. |
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 nodes.
|
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<?,?,?,?>> |
getTypeFactoryOfSubchecker(Class<? extends BaseTypeChecker> subCheckerClass)
Returns the type factory used by a subchecker.
|
protected void |
handleCFGViz(ControlFlowGraph cfg)
Handle the visualization of the CFG, if necessary.
|
boolean |
isRelevant(TypeMirror tm)
Returns true if users can write type annotations from this type system on the given Java type.
|
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.
|
JavaExpression |
parseJavaExpressionString(String expression,
TreePath currentPath)
Produces the JavaExpression as if
expression were written at currentPath . |
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, addAliasedDeclAnnotation, addAliasedTypeAnnotation, addAliasedTypeAnnotation, addAliasedTypeAnnotation, addAliasedTypeAnnotation, addAnnotationFromFieldInvariant, addInheritedAnnotation, applyCaptureConversion, applyCaptureConversion, applyUnboxing, areSameByClass, binaryTreeArgTypes, binaryTreeArgTypes, canonicalAnnotation, checkInvalidOptionsInferSignatures, compoundAssignmentTreeArgTypes, containsSameByClass, containsUninferredTypeArguments, createAnnotatedTypeFormatter, createAnnotationClassLoader, createAnnotationFormatter, createQualifierHierarchy, createQualifierUpperBounds, createSupportedTypeQualifiers, createTypeArgumentInference, createTypeHierarchy, createTypeVariableSubstitutor, declarationFromElement, doesAnnotatedForApplyToThisChecker, fromElement, fromElement, fromElement, fromNewClass, getAnnotatedNullType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedTypeFormatter, getAnnotatedTypeFromTypeTree, getAnnotationByClass, getAnnotationFormatter, getAnnotationMirror, getAnnotationWithMetaAnnotation, getBoxedType, getBundledTypeQualifiers, getCacheSize, getChecker, getCheckerNames, getContractExpressions, getContractListValues, getCurrentClassTree, getCurrentMethodReceiver, getDeclAnnotation, getDeclAnnotationNoAliases, getDeclAnnotations, getDeclAnnotationWithMetaAnnotation, getDefaultTypeDeclarationBounds, getDummyAssignedTo, getElementUtils, getEnclosingClassOrMethod, getEnclosingElementForArtificialTree, getEnclosingType, getExpressionAndOffset, getFieldInvariantAnnotationTree, getFieldInvariantDeclarationAnnotations, getFieldInvariants, getFnInterfaceFromTree, getFunctionTypeFromTree, getFunctionTypeFromTree, getImplicitReceiverType, getIterableElementType, getIterableElementType, getMethodReturnType, getNarrowedAnnotations, getNarrowedPrimitive, getPath, getProcessingEnv, getQualifierHierarchy, getQualifierParameterHierarchies, getQualifierParameterHierarchies, getQualifierUpperBounds, getReceiverType, getSelfType, getStringType, getSupportedTypeQualifierNames, getSupportedTypeQualifiers, getTreeUtils, getTypeArgumentInference, getTypeDeclarationBounds, getTypeHierarchy, getTypeOfExtendsImplements, getTypeVarSubstitutor, getUnboxedType, getUninferredWildcardType, getVisitorTreePath, getWholeProgramInference, getWidenedAnnotations, getWidenedType, getWidenedType, hasExplicitNoQualifierParameterInHierarchy, hasExplicitQualifierParameterInHierarchy, hasQualifierParameterInHierarchy, hasQualifierParameterInHierarchy, initializeAtm, initializeReflectionResolution, isFromByteCode, isFromStubFile, isImmutable, isSupportedQualifier, isSupportedQualifier, isSupportedQualifier, isWithinConstructor, mergeAnnotationFileAnnosIntoType, methodFromUse, negateConstant, order, parseAnnotationFiles, postProcessClassTree, prepareMethodForWriting, prepareMethodForWriting, replaceAnnotations, replaceAnnotations, setEnclosingElementForArtificialTree, setVisitorTreePath, shouldWarnIfStubRedundantWithBytecode, toAnnotatedType, toString, type, wpiAdjustForUpdateField, wpiAdjustForUpdateNonField
protected static boolean flowByDefault
protected TypeAnnotator typeAnnotator
protected TreeAnnotator treeAnnotator
protected QualifierPolymorphism poly
protected QualifierDefaults defaults
protected DependentTypesHelper dependentTypesHelper
protected ContractsFromMethod contractsUtils
public @Nullable Set<TypeMirror> relevantJavaTypes
#arraysAreRelevant
.
If the relevant type is generic, this contains its erasure.
Although a Class<?>
object exists for every element, this does not contain those
Class<?>
objects because the elements will be compared to TypeMirrors for which Class
objects may not exist (they might not be on the classpath).
public boolean sideEffectsUnrefineAliases
For many type systems, once a local variable's type is refined, side effects to the variable's value do not change the variable's type annotations. For some type systems, a side effect to the value could change them; set this field to true.
public final boolean hasOrIsSubchecker
addSharedCFGForTree(Tree, ControlFlowGraph)
and getSharedCFGForTree(Tree)
should be guarded by a check that this is true.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, Analysis.BeforeOrAfter, TransferInput,
IdentityHashMap, Map)
. This cache is enabled if AnnotatedTypeFactory.shouldCache
is true. The cache size
is derived from AnnotatedTypeFactory.getCacheSize()
.protected @Nullable Map<Tree,ControlFlowGraph> subcheckerSharedCFG
The initial capacity of the map is set by AnnotatedTypeFactory.getCacheSize()
.
protected boolean shouldClearSubcheckerSharedCFGs
setRoot(CompilationUnitTree)
should clear the subcheckerSharedCFG
map, freeing memory.
For each compilation unit, all the subcheckers run first and finally the ultimate parent
checker runs. The ultimate parent checker's setRoot(CompilationUnitTree)
(the last to
run) sets this field to true.
In first subchecker to run for the next compilation unit, setRoot(CompilationUnitTree)
observes the true value, clears the subcheckerSharedCFG
map, and sets this field back to false. That first subchecker will create a CFG and re-populate
the map, and subsequent subcheckers will use the map.
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 static final Pattern formalParameterPattern
EnsuresQualifier
and RequiresQualifier
annotations, e.g. "#1", "#2", etc.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
public DefaultForTypeAnnotator getDefaultForTypeAnnotator()
DefaultForTypeAnnotator
.DefaultForTypeAnnotator
protected FlowAnalysis createFlowAnalysis()
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. Use getDependentTypesHelper()
to
access the value.DependentTypesHelper
public DependentTypesHelper getDependentTypesHelper()
protected ContractsFromMethod createContractsFromMethod()
ContractsFromMethod
and returns it.ContractsFromMethod
public ContractsFromMethod getContractsFromMethod()
protected List<AnnotatedTypeMirror> getExplicitNewClassClassTypeArgs(NewClassTree newClassTree)
AnnotatedTypeFactory
AnnotatedTypeMirror
only include the annotations explicitly written on the explict type
arguments. (If newClass
use a diamond operator, this method returns the empty list.)
For example, when called with new MyClass<@HERE String>()
this method would return a
list containing @HERE String
.getExplicitNewClassClassTypeArgs
in class AnnotatedTypeFactory
newClassTree
- a new class treeAnnotatedTypeMirror
s for the (explicit) class type
arguments of the new class treepublic Set<AnnotationMirror> getExplicitNewClassAnnos(NewClassTree newClassTree)
AnnotatedTypeFactory
new @HERE Class()
getExplicitNewClassAnnos
in class AnnotatedTypeFactory
newClassTree
- a constructor invocationprotected 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 JavaExpressionParseUtil.JavaExpressionParseException
expression
- a Java expressiontree
- current treepath
- location at which expression is evaluatedclazz
- class of the annotationJavaExpressionParseUtil.JavaExpressionParseException
- thrown if the expression cannot be parsedpublic AnnotationMirror getAnnotationFromJavaExpression(JavaExpression expr, Tree tree, Class<? extends Annotation> clazz)
expr
- the expression for which the annotation is returnedtree
- current treeclazz
- the Class of the annotationpublic Set<AnnotationMirror> getAnnotationsFromJavaExpression(JavaExpression expr, Tree tree)
expr
- the expression for which the annotation is returnedtree
- current treepublic JavaExpression parseJavaExpressionString(String expression, TreePath currentPath) throws JavaExpressionParseUtil.JavaExpressionParseException
expression
were written at currentPath
.expression
- a Java expressioncurrentPath
- the current pathJavaExpressionParseUtil.JavaExpressionParseException
- thrown if the expression cannot be parsedpublic Pair<JavaExpression,String> getExpressionAndOffsetFromJavaExpressionString(String expression, TreePath currentPath) throws JavaExpressionParseUtil.JavaExpressionParseException
expression
- a Java expression, possibly with a constant offsetcurrentPath
- location at which expression is evaluatedJavaExpressionParseUtil.JavaExpressionParseException
- thrown if the expression cannot be parsedpublic AnnotationMirror getAnnotationMirrorFromJavaExpressionString(String expression, Tree tree, TreePath currentPath) throws JavaExpressionParseUtil.JavaExpressionParseException
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 evaluatedJavaExpressionParseUtil.JavaExpressionParseException
- 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 storepublic 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
- a node whose pre-store to returnnode
public Store getStoreAfter(Tree tree)
May return null; for example, after a return
statement.
tree
- the tree whose post-store to returnpublic Store getStoreAfter(Set<Node> nodes)
nodes
- the nodes whose post-stores to LUBnodes
public 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.
T
- the class of the node to returntree
- a tree in which to search for a node of class kind
kind
- the class of the node to returnNode
for a given Tree
that has class kind
getNodesForTree(Tree)
,
getStoreBefore(Tree)
,
getStoreAfter(Tree)
public HashMap<Element,Value> getFinalLocalValues()
protected void performFlowAnalysis(ClassTree classTree)
classTree
- the class to analyzeprotected void analyze(Queue<Pair<ClassTree,Store>> queue, Queue<Pair<LambdaExpressionTree,Store>> lambdaQueue, UnderlyingAST ast, List<CFAbstractAnalysis.FieldInitialValue<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)
v + 1
or v - 1
where v
is the expression in the
postfixed increment or decrement expression.tree
- a postfixed increment or decrement treepublic 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>, java.lang.CharSequence, 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
- tree of a method declarationpublic 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)
tree
- the treeprotected 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
- a 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
- an 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>, java.lang.CharSequence, 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<?,?,?,?>> T getTypeFactoryOfSubchecker(Class<? extends BaseTypeChecker> subCheckerClass)
Because the visitor path is copied, call this method each time a subfactory is needed rather than store the returned subfactory in a field.
T
- the type of subCheckerClass
's AnnotatedTypeFactory
subCheckerClass
- the exact class of the subcheckerpublic 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 @Nullable 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 addedpublic boolean isRelevant(TypeMirror tm)
tm
- a typepublic AnnotatedTypeMirror getDefaultValueAnnotatedType(TypeMirror typeMirror)
typeMirror
- a typetype
's default valuepublic List<AnnotationMirror> getContractAnnotations(scenelib.annotations.el.AMethod m)
m
- AFU representation of a methodpublic List<AnnotationMirror> getPreconditionAnnotations(scenelib.annotations.el.AMethod m)
m
- AFU representation of a methodpublic List<AnnotationMirror> getPostconditionAnnotations(scenelib.annotations.el.AMethod m, List<AnnotationMirror> preconds)
m
- AFU representation of a methodpreconds
- the precondition annotations for the method; used to suppress redundant
postconditionspublic List<AnnotationMirror> getContractAnnotations(WholeProgramInferenceJavaParserStorage.CallableDeclarationAnnos methodAnnos)
methodAnnos
- annotation data for a methodpublic List<AnnotationMirror> getPreconditionAnnotations(WholeProgramInferenceJavaParserStorage.CallableDeclarationAnnos methodAnnos)
methodAnnos
- annotation data for a methodpublic List<AnnotationMirror> getPostconditionAnnotations(WholeProgramInferenceJavaParserStorage.CallableDeclarationAnnos methodAnnos, List<AnnotationMirror> preconds)
methodAnnos
- annotation data for a methodpreconds
- the precondition annotations for the method; used to suppress redundant
postconditionspublic final List<AnnotationMirror> getPreconditionAnnotations(String expression, AnnotatedTypeMirror inferredType, AnnotatedTypeMirror declaredType)
@RequiresQualifier
annotations for the given expression. By
default this list does not include any qualifier that has elements/arguments, which
@RequiresQualifier
does not support. Subclasses may remove this restriction by
overriding createRequiresOrEnsuresQualifier(java.lang.String, javax.lang.model.element.AnnotationMirror, org.checkerframework.framework.type.AnnotatedTypeMirror, org.checkerframework.dataflow.analysis.Analysis.BeforeOrAfter, java.util.List<javax.lang.model.element.AnnotationMirror>)
.
Each annotation in the list is of the form
@RequiresQualifier(expression="expression", qualifier=MyQual.class)
. expression
must be a valid Java Expression string, in the same format used by RequiresQualifier
.
expression
- an expressioninferredType
- the type of the expression, on method entrydeclaredType
- the declared type of the expressionpublic final List<AnnotationMirror> getPostconditionAnnotations(String expression, AnnotatedTypeMirror inferredType, AnnotatedTypeMirror declaredType, List<AnnotationMirror> preconds)
@EnsuresQualifier
annotations for the given expression. By
default this list does not include any qualifier that has elements/arguments, which
@EnsuresQualifier
does not support; and, preconditions are not used to suppress
redundant postconditions. Subclasses may remove these restrictions by overriding createRequiresOrEnsuresQualifier(java.lang.String, javax.lang.model.element.AnnotationMirror, org.checkerframework.framework.type.AnnotatedTypeMirror, org.checkerframework.dataflow.analysis.Analysis.BeforeOrAfter, java.util.List<javax.lang.model.element.AnnotationMirror>)
.
Each annotation in the list is of the form @EnsuresQualifier(expression="expression",
qualifier=MyQual.class)
. expression
must be a valid Java Expression string, in the
same format used by EnsuresQualifier
.
expression
- an expressioninferredType
- the type of the expression, on method exitdeclaredType
- the declared type of the expressionpreconds
- the precondition annotations for the method; used to suppress redundant
postconditionsprotected List<AnnotationMirror> getPreOrPostconditionAnnotations(String expression, AnnotatedTypeMirror inferredType, AnnotatedTypeMirror declaredType, Analysis.BeforeOrAfter preOrPost, @Nullable List<AnnotationMirror> preconds)
getPreconditionAnnotations(scenelib.annotations.el.AMethod)
and getPostconditionAnnotations(scenelib.annotations.el.AMethod, java.util.List<javax.lang.model.element.AnnotationMirror>)
.
Returns a @RequiresQualifier
or @EnsuresQualifier
annotation for the given
expression. Returns an empty list if none can be created, because the qualifier has
elements/arguments, which @RequiresQualifier
and @EnsuresQualifier
do not
support.
This implementation makes no assumptions about preconditions suppressing postconditions, but subclasses may do so.
expression
- an expression whose type annotations to returninferredType
- the type of the expression, on method entry or exit (depending on the value
of preOrPost
)declaredType
- the declared type of the expression, which is used to determine if the
inferred type supplies no additional information beyond the declared typepreOrPost
- whether to return preconditions or postconditionspreconds
- the precondition annotations for the method; used to suppress redundant
postconditions; non-null exactly when preOrPost
is AFTER
protected @Nullable AnnotationMirror createRequiresOrEnsuresQualifier(String expression, AnnotationMirror qualifier, AnnotatedTypeMirror declaredType, Analysis.BeforeOrAfter preOrPost, @Nullable List<AnnotationMirror> preconds)
RequiresQualifier("...")
or EnsuresQualifier("...")
annotation for
the given expression.
This is of the form @RequiresQualifier(expression="expression",
qualifier=MyQual.class)
or @EnsuresQualifier(expression="expression",
qualifier=MyQual.class)
, where "expression" is exactly the string expression
and
MyQual is the annotation represented by qualifier
.
Returns null if the expression is invalid when combined with the kind of annotation: for example, precondition annotations on "this" and parameters ("#1", etc.) are not supported, because receiver/parameter annotations should be inferred instead.
This implementation returns null if no annotation can be created, because the qualifier has
elements/arguments, which @RequiresQualifier
and @EnsuresQualifier
do not
support. Subclasses may override this method to return qualifiers that do have arguments
instead of returning null.
expression
- the expression to which the qualifier appliesqualifier
- the qualifier that must be presentdeclaredType
- the declared type of the expression, which is used to avoid inferring
redundant pre- or postcondition annotationspreOrPost
- whether to return a precondition or postcondition annotationpreconds
- the list of precondition annotations; used to suppress redundant
postconditions; non-null exactly when preOrPost
is BeforeOrAfter.BEFORE
RequiresQualifier("...")
or EnsuresQualifier("...")
annotation for
the given expression, or nullpublic boolean addSharedCFGForTree(Tree tree, ControlFlowGraph cfg)
Calls to this method should be guarded by checking hasOrIsSubchecker
; it is
nonsensical to have a shared CFG when a checker is running alone.
tree
- the source code corresponding to cfgcfg
- the control flow graph to use for treepublic @Nullable ControlFlowGraph getSharedCFGForTree(Tree tree)
tree
by this checker's topmost superchecker.
Returns null if no information is available about the given tree, or if this checker has a
parent checker that does not have a GenericAnnotatedTypeFactory.
Calls to this method should be guarded by checking hasOrIsSubchecker
; it is
nonsensical to have a shared CFG when a checker is running alone.
tree
- the tree whose CFG should be looked uppublic Boolean getEnsuresQualifierIfResult(Contract.Kind kind, AnnotationMirror contractAnnotation)
EnsuresQualifierIf.result()
. Otherwise, return null.kind
- the kind of contractAnnotation
contractAnnotation
- a RequiresQualifier
, EnsuresQualifier
, or EnsuresQualifierIf
result
element of contractAnnotation
, or null if it doesn't have a
result
elementpublic List<String> getContractExpressions(Contract.Kind kind, AnnotationMirror contractAnnotation)
contractAnnotation
is a framework annotation, return its expression
element.
Otherwise, contractAnnotation
is defined in a checker. If kind =
CONDITIONALPOSTCONDITION, return its expression
element, else return its value
element.kind
- the kind of contractAnnotation
contractAnnotation
- a RequiresQualifier
, EnsuresQualifier
, or EnsuresQualifierIf
result
element of contractAnnotation
, or null if it doesn't have a
result
element