public class NullnessAnnotatedTypeFactory extends InitializationAnnotatedTypeFactory<NullnessValue,NullnessStore,NullnessTransfer,NullnessAnalysis>
| Modifier and Type | Class and Description |
|---|---|
protected class |
NullnessAnnotatedTypeFactory.NullnessPropagationAnnotator
Nullness doesn't call propagation on binary and unary because the result is
always @Initialized (the default qualifier).
|
protected class |
NullnessAnnotatedTypeFactory.NullnessQualifierHierarchy |
protected class |
NullnessAnnotatedTypeFactory.NullnessTreeAnnotator |
protected class |
NullnessAnnotatedTypeFactory.NullnessTypeAnnotator |
InitializationAnnotatedTypeFactory.CommitmentTreeAnnotator, InitializationAnnotatedTypeFactory.CommitmentTypeAnnotator, InitializationAnnotatedTypeFactory.InitializationQualifierHierarchyGenericAnnotatedTypeFactory.ScanStateAnnotatedTypeFactory.InheritedFromClassAnnotator| Modifier and Type | Field and Description |
|---|---|
protected CollectionToArrayHeuristics |
collectionToArrayHeuristics |
protected DependentTypes |
dependentTypes
Dependent types instance.
|
protected GeneralAnnotatedTypeFactory |
generalFactory
Factory for arbitrary qualifiers, used for declarations and "unused" qualifier.
|
protected AnnotationMirror |
MONOTONIC_NONNULL
Annotation constants
|
protected AnnotationMirror |
NONNULL
Annotation constants
|
protected AnnotationMirror |
NULLABLE
Annotation constants
|
protected Set<Class<? extends Annotation>> |
nullnessAnnos
Cache for the nullness annotations
|
protected AnnotationMirror |
POLYNULL
Annotation constants
|
protected SystemGetPropertyHandler |
systemGetPropertyHandler |
COMMITTED, FBCBOTTOM, FREE, initAnnos, NOT_ONLY_COMMITTED, UNCLASSIFIED, useFbcanalyses, cfgVisualizer, defaults, dependentTypesHelper, FLOW_BY_DEFAULT, flowResult, initializationStaticStore, initializationStore, methodInvocationStores, poly, regularExitStores, returnStatementStores, scannedClasses, treeAnnotator, typeAnnotatorchecker, elements, fromTreeCache, loader, processingEnv, qualHierarchy, reflectionResolver, root, shouldCache, trees, typeArgumentInference, typeFormatter, typeHierarchy, types, typeVarSubstitutor, uid, visitorState| Constructor and Description |
|---|
NullnessAnnotatedTypeFactory(BaseTypeChecker checker,
boolean useFbc) |
| Modifier and Type | Method and Description |
|---|---|
protected void |
addComputedTypeAnnotations(Tree tree,
AnnotatedTypeMirror type,
boolean useFlow)
Like {#addComputedTypeAnnotations(Tree, AnnotatedTypeMirror)}.
|
Pair<AnnotatedTypeMirror.AnnotatedExecutableType,List<AnnotatedTypeMirror>> |
constructorFromUse(NewClassTree tree)
Determines the type of the invoked constructor based on the passed new class tree.
|
protected AnnotatedTypeFormatter |
createAnnotatedTypeFormatter()
Creates the AnnotatedTypeFormatter used by this type factory and all AnnotatedTypeMirrors it
creates.
|
protected NullnessAnalysis |
createFlowAnalysis(List<Pair<VariableElement,NullnessValue>> fieldValues)
Returns the appropriate flow analysis class that is used for the
org.checkerframework.dataflow analysis.
|
NullnessTransfer |
createFlowTransferFunction(CFAbstractAnalysis<NullnessValue,NullnessStore,NullnessTransfer> analysis)
Returns the appropriate transfer function that is used for the org.checkerframework.dataflow
analysis.
|
QualifierHierarchy |
createQualifierHierarchy(MultiGraphQualifierHierarchy.MultiGraphFactory factory)
Factory method to easily change what QualifierHierarchy is created.
|
protected Set<Class<? extends Annotation>> |
createSupportedTypeQualifiers()
Returns a mutable set of annotation classes that are supported by a checker
|
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. |
AnnotationMirror |
getFieldInvariantAnnotation()
Returns the annotation that makes up the invariant of this commitment type system, such as
@NonNull. |
Set<Class<? extends Annotation>> |
getInvalidConstructorReturnTypeAnnotations() |
AnnotatedTypeMirror |
getMethodReturnType(MethodTree m,
ReturnTree r)
Returns the return type of the method
m at the return statement r. |
Set<Class<? extends Annotation>> |
getNullnessAnnotations() |
List<VariableTree> |
getUninitializedInvariantFields(NullnessStore store,
TreePath path,
boolean isStatic,
List<? extends AnnotationMirror> receiverAnnotations)
Returns the (non-static) fields that have the invariant annotation and are not yet
initialized in a given store.
|
Pair<AnnotatedTypeMirror.AnnotatedExecutableType,List<AnnotatedTypeMirror>> |
methodFromUse(MethodInvocationTree tree)
Determines the type of the invoked method based on the passed method invocation tree.
|
protected void |
replacePolyQualifier(AnnotatedTypeMirror lhsType,
Tree context)
|
void |
setRoot(CompilationUnitTree root) |
areAllFieldsCommittedOnly, createFreeAnnotation, createFreeAnnotation, createQualifierHierarchyFactory, createUnclassifiedAnnotation, createUnclassifiedAnnotation, getAnnotatedTypeLhs, getFreeOrRawAnnotationOfSuperType, getInitializationAnnotations, getInitializedInvariantFields, getSelfType, getTypeFrameFromAnnotation, isCommitted, isCommitted, isFbcBottom, isFbcBottom, isFree, isFree, isInitializationAnnotation, isInitializedForFrame, isUnclassified, isUnclassified, postAsMemberOf, setSelfTypeInInitializationCodeaddCheckedCodeDefaults, addCheckedStandardDefaults, addComputedTypeAnnotations, addComputedTypeAnnotations, addTypeNameImplicit, addUncheckedCodeDefaults, addUncheckedStandardDefaults, analyze, analyze, applyInferredAnnotations, checkAndPerformFlowAnalysis, checkForDefaultQualifierInHierarchy, createCFGVisualizer, createDependentTypesHelper, createQualifierDefaults, createQualifierPolymorphism, fromNewClass, getAnnotatedTypeLhsNoTypeVarDefault, getAnnotationFromJavaExpressionString, getCFGVisualizer, getDependentTypesHelper, getEmptyStore, getFinalLocalValues, getInferredValueFor, getMethodReturnType, getNodeForTree, getReceiverFromJavaExpressionString, getRegularExitStore, getResultingTypeOfConstructorMemberReference, getReturnStatementStores, getShouldDefaultTypeVarLocals, getSortedQualifierNames, getStoreAfter, getStoreBefore, getStoreBefore, getSupportedMonotonicTypeQualifiers, getTypeFactoryOfSubchecker, handleCFGViz, performFlowAnalysis, postDirectSuperTypes, postInit, preProcessClassTree, typeVariablesFromUseadaptGetClassReturnTypeToReceiver, addAliasedAnnotation, addAliasedDeclAnnotation, addInheritedAnnotation, aliasedAnnotation, annotateInheritedFromClass, annotateInheritedFromClass, checkInvalidOptionsInferSignatures, createAnnotationFormatter, createQualifierHierarchy, createQualifierHierarchy, createTypeArgumentInference, createTypeHierarchy, createTypeVariableSubstitutor, declarationFromElement, fromElement, fromElement, fromElement, getAnnotatedNullType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedTypeFromTypeTree, getAnnotationFormatter, getAnnotationMirror, getAnnotationWithMetaAnnotation, getBoxedType, getBundledTypeQualifiersWithoutPolyAll, getBundledTypeQualifiersWithPolyAll, getContext, getCurrentClassTree, getCurrentClassType, getCurrentMethodReceiver, getDeclAnnotation, getDeclAnnotationNoAliases, getDeclAnnotations, getDeclAnnotationWithMetaAnnotation, getElementUtils, getEnclosingMethod, getEnclosingType, getFnInterfaceFromTree, getFnInterfaceFromTree, getImplicitReceiverType, getNarrowedPrimitive, getPath, getProcessingEnv, getQualifierHierarchy, getReceiverType, getStringType, getSupportedTypeQualifiers, getTreeUtils, getTypeArgumentInference, getTypeHierarchy, getTypeVarSubstitutor, getUnboxedType, getUninferredWildcardType, getVisitorState, getWholeProgramInference, initilizeReflectionResolution, isAnyEnclosingThisDeref, isFromByteCode, isFromStubFile, isMostEnclosingThisDeref, isSupportedQualifier, isWithinConstructor, methodFromUse, parseStubFiles, postProcessClassTree, postTypeVarSubstitution, setPathHack, toAnnotatedType, toString, type, widenToUpperBoundprotected final AnnotationMirror NONNULL
protected final AnnotationMirror NULLABLE
protected final AnnotationMirror POLYNULL
protected final AnnotationMirror MONOTONIC_NONNULL
protected final DependentTypes dependentTypes
protected final SystemGetPropertyHandler systemGetPropertyHandler
protected final CollectionToArrayHeuristics collectionToArrayHeuristics
protected final GeneralAnnotatedTypeFactory generalFactory
protected final Set<Class<? extends Annotation>> nullnessAnnos
public NullnessAnnotatedTypeFactory(BaseTypeChecker checker, boolean useFbc)
protected Set<Class<? extends Annotation>> createSupportedTypeQualifiers()
AnnotatedTypeFactorySubclasses may override this method and to return a mutable set of their supported type qualifiers through one of the 5 approaches shown below.
Subclasses should not call this method; they should call AnnotatedTypeFactory.getSupportedTypeQualifiers() instead.
By default, a checker supports PolyAll, and all annotations located in a
subdirectory called qual that's located in the same directory as the checker. Note
that only annotations defined with the @Target({ElementType.TYPE_USE})
meta-annotation (and optionally with the additional value of ElementType.TYPE_PARAMETER, but no other ElementType values) are automatically
considered as supported annotations.
Annotations located outside the qual subdirectory, or has other ElementType values must be explicitly listed in code by overriding the AnnotatedTypeFactory.createSupportedTypeQualifiers() method, as shown below.
Lastly, for checkers that do not want to support PolyAll, it must also be
explicitly written in code, as shown below.
In total, there are 5 ways to indicate annotations that are supported by a checker:
PolyAll:
This is the default behavior. Simply place those annotations within the qual directory.
PolyAll:
Place those annotations within the qual directory, and override AnnotatedTypeFactory.createSupportedTypeQualifiers() by calling AnnotatedTypeFactory.getBundledTypeQualifiersWithPolyAll(Class...) with no parameters passed in. Code
example:
@Override protected Set<Class<? extends Annotation>> createSupportedTypeQualifiers() {
return getBundledTypeQualifiersWithoutPolyAll();
}
PolyAll,
and a list of other annotations:
Place those annotations within the qual directory, and override AnnotatedTypeFactory.createSupportedTypeQualifiers() by calling AnnotatedTypeFactory.getBundledTypeQualifiersWithPolyAll(Class...) with a varargs parameter list of the
other annotations. Code example:
@Override protected Set<Class<? extends Annotation>> createSupportedTypeQualifiers() {
return getBundledTypeQualifiersWithPolyAll(Regex.class, PartialRegex.class, RegexBottom.class, UnknownRegex.class);
}
PolyAll:
Place those annotations within the qual directory, and override AnnotatedTypeFactory.createSupportedTypeQualifiers() by calling AnnotatedTypeFactory.getBundledTypeQualifiersWithoutPolyAll(Class...) with a varargs parameter list of the
other annotations. Code example:
@Override protected Set<Class<? extends Annotation>> createSupportedTypeQualifiers() {
return getBundledTypeQualifiersWithoutPolyAll(UnknownFormat.class, FormatBottom.class);
}
AnnotatedTypeFactory.createSupportedTypeQualifiers() and return a mutable set of the supported
annotations. Code example:
@Override protected Set<Class<? extends Annotation>> createSupportedTypeQualifiers() {
return new HashSet<Class<? extends Annotation>>(
Arrays.asList(A.class, B.class));
}
The set of qualifiers returned by AnnotatedTypeFactory.createSupportedTypeQualifiers() must be a
fresh, mutable set. The methods AnnotatedTypeFactory.getBundledTypeQualifiersWithoutPolyAll(Class...) and AnnotatedTypeFactory.getBundledTypeQualifiersWithPolyAll(Class...) each must return a fresh, mutable set
createSupportedTypeQualifiers in class AnnotatedTypeFactorypublic void setRoot(CompilationUnitTree root)
setRoot in class GenericAnnotatedTypeFactory<NullnessValue,NullnessStore,NullnessTransfer,NullnessAnalysis>protected void addComputedTypeAnnotations(Tree tree, AnnotatedTypeMirror type, boolean useFlow)
GenericAnnotatedTypeFactoryprotected void replacePolyQualifier(AnnotatedTypeMirror lhsType, Tree context)
PolyNull or PolyAll with Nullable if the org.checkerframework.dataflow analysis has determined
that this is allowed soundly. For example:
@PolyNull String foo(@PolyNull String param) {
if (param == null) {
// @PolyNull is really @Nullable, so change
// the type of param to @Nullable.
param = null;
}
return param;
}
lhsType - type to replace whose polymorphic qualifier will be replacedcontext - tree used to get dataflow valuepublic Pair<AnnotatedTypeMirror.AnnotatedExecutableType,List<AnnotatedTypeMirror>> constructorFromUse(NewClassTree tree)
AnnotatedTypeFactoryThe 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 GenericAnnotatedTypeFactory<NullnessValue,NullnessStore,NullnessTransfer,NullnessAnalysis>tree - the constructor invocation treepublic List<VariableTree> getUninitializedInvariantFields(NullnessStore store, TreePath path, boolean isStatic, List<? extends AnnotationMirror> receiverAnnotations)
InitializationAnnotatedTypeFactoryprotected NullnessAnalysis createFlowAnalysis(List<Pair<VariableElement,NullnessValue>> fieldValues)
GenericAnnotatedTypeFactoryThis 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.
createFlowAnalysis in class GenericAnnotatedTypeFactory<NullnessValue,NullnessStore,NullnessTransfer,NullnessAnalysis>public NullnessTransfer createFlowTransferFunction(CFAbstractAnalysis<NullnessValue,NullnessStore,NullnessTransfer> analysis)
GenericAnnotatedTypeFactoryThis 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 AnnotatedTypeFormatter createAnnotatedTypeFormatter()
AnnotatedTypeFactorycreateAnnotatedTypeFormatter in class AnnotatedTypeFactorypublic Pair<AnnotatedTypeMirror.AnnotatedExecutableType,List<AnnotatedTypeMirror>> methodFromUse(MethodInvocationTree tree)
AnnotatedTypeFactoryThe 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 GenericAnnotatedTypeFactory<NullnessValue,NullnessStore,NullnessTransfer,NullnessAnalysis>tree - the method invocation treepublic AnnotatedTypeMirror getMethodReturnType(MethodTree m, ReturnTree r)
AnnotatedTypeFactorym at the return statement r.getMethodReturnType in class GenericAnnotatedTypeFactory<NullnessValue,NullnessStore,NullnessTransfer,NullnessAnalysis>protected TypeAnnotator createTypeAnnotator()
GenericAnnotatedTypeFactoryImplicitsTypeAnnotator
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
createTypeAnnotator in class InitializationAnnotatedTypeFactory<NullnessValue,NullnessStore,NullnessTransfer,NullnessAnalysis>protected TreeAnnotator createTreeAnnotator()
GenericAnnotatedTypeFactoryTreeAnnotator that adds annotations to a type based on the contents of a
tree.
Subclasses may override this method to specify a more appropriate TreeAnnotator.
The default tree annotator is a ListTreeAnnotator of the following:
PropagationTreeAnnotator: Propagates annotations from subtrees.
ImplicitsTreeAnnotator: Adds annotations based on ImplicitFor
meta-annotations
createTreeAnnotator in class InitializationAnnotatedTypeFactory<NullnessValue,NullnessStore,NullnessTransfer,NullnessAnalysis>public Set<Class<? extends Annotation>> getNullnessAnnotations()
public Set<Class<? extends Annotation>> getInvalidConstructorReturnTypeAnnotations()
getInvalidConstructorReturnTypeAnnotations in class InitializationAnnotatedTypeFactory<NullnessValue,NullnessStore,NullnessTransfer,NullnessAnalysis>public AnnotationMirror getFieldInvariantAnnotation()
InitializationAnnotatedTypeFactory@NonNull.public QualifierHierarchy createQualifierHierarchy(MultiGraphQualifierHierarchy.MultiGraphFactory factory)
AnnotatedTypeFactorycreateQualifierHierarchy in class AnnotatedTypeFactory