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