public class SameLenAnnotatedTypeFactory extends BaseAnnotatedTypeFactory
This annotated type factory refines types in X cases:
@PolyAll
and @PolyLength
are refined to @PolySameLen
.
@SameLen
annotation, then the type
of the new variable is the union of the user-written arrays in the annotation and the
arrays listed in the SameLen types of each of those arrays.
new T[a.length]
is the union of the
SameLen type of a
and the arrays listed in a
's SameLen type.
Modifier and Type | Class and Description |
---|---|
protected class |
SameLenAnnotatedTypeFactory.SameLenTreeAnnotator
SameLen needs a tree annotator in order to properly type the right side of assignments of new
arrays that are initialized with the length of another array.
|
GenericAnnotatedTypeFactory.ScanState
AnnotatedTypeFactory.InheritedFromClassAnnotator, AnnotatedTypeFactory.ParameterizedMethodType
Modifier and Type | Field and Description |
---|---|
AnnotationMirror |
UNKNOWN |
analysis, cfgVisualizer, defaults, dependentTypesHelper, emptyStore, flowByDefault, flowResult, flowResultAnalysisCaches, initializationStaticStore, initializationStore, methodInvocationStores, poly, regularExitStores, returnStatementStores, scannedClasses, transfer, treeAnnotator, typeAnnotator
checker, elements, fromExpressionTreeCache, fromMemberTreeCache, fromTypeTreeCache, ignoreUninferredTypeArguments, loader, processingEnv, qualHierarchy, reflectionResolver, root, shouldCache, trees, typeArgumentInference, typeFormatter, typeHierarchy, types, typeVarSubstitutor, uid, visitorState
Constructor and Description |
---|
SameLenAnnotatedTypeFactory(BaseTypeChecker checker)
Handles case 1.
|
Modifier and Type | Method and Description |
---|---|
AnnotationMirror |
createCombinedSameLen(FlowExpressions.Receiver rec1,
FlowExpressions.Receiver rec2,
AnnotationMirror a1,
AnnotationMirror a2)
Combines the given arrays and annotations into a single SameLen annotation.
|
AnnotationMirror |
createCombinedSameLen(List<FlowExpressions.Receiver> receivers,
List<AnnotationMirror> annos)
For the use of the transfer function; generates a SameLen that includes a and b, as well as
everything in sl1 and sl2, if they are SameLen annotations.
|
QualifierHierarchy |
createQualifierHierarchy(MultiGraphQualifierHierarchy.MultiGraphFactory factory)
Factory method to easily change what QualifierHierarchy is created.
|
AnnotationMirror |
createSameLen(String... val)
Creates a @SameLen annotation whose values are the given strings.
|
protected Set<Class<? extends Annotation>> |
createSupportedTypeQualifiers()
Returns a mutable set of annotation classes that are supported by a checker.
|
TreeAnnotator |
createTreeAnnotator()
Returns a
TreeAnnotator that adds annotations to a type based on the contents of a
tree. |
AnnotatedTypeMirror |
getAnnotatedTypeLhs(Tree tree)
Handles case 2.
|
AnnotationMirror |
getCombinedSameLen(List<String> a1Names,
List<String> a2Names)
This function finds the union of the values of two annotations.
|
List<String> |
getSameLensFromString(String sequenceExpression,
Tree tree,
TreePath currentPath)
Find all the sequences that are members of the SameLen annotation associated with the
sequence named in sequenceExpression along the current path.
|
static boolean |
shouldUseInAnnotation(FlowExpressions.Receiver receiver) |
createFlowAnalysis
addCheckedCodeDefaults, addCheckedStandardDefaults, addComputedTypeAnnotations, addComputedTypeAnnotations, addComputedTypeAnnotations, addDefaultAnnotations, addTypeNameImplicit, addUncheckedCodeDefaults, addUncheckedStandardDefaults, analyze, applyInferredAnnotations, checkAndPerformFlowAnalysis, checkForDefaultQualifierInHierarchy, constructorFromUse, createAndInitQualifierDefaults, createCFGVisualizer, createDependentTypesHelper, createFlowTransferFunction, createQualifierDefaults, createQualifierPolymorphism, createTypeAnnotator, fromNewClass, getAnnotatedTypeLhsNoTypeVarDefault, getAnnotatedTypeRhsUnaryAssign, getAnnotatedTypeVarargsArray, getAnnotationFromJavaExpressionString, getAnnotationFromReceiver, getAnnotationMirrorFromJavaExpressionString, getCFGVisualizer, getDependentTypesHelper, getEmptyStore, getFinalLocalValues, getFirstNodeOfKindForTree, getInferredValueFor, getMethodReturnType, getMethodReturnType, getNodesForTree, getQualifierPolymorphism, getReceiverFromJavaExpressionString, getRegularExitStore, getResultingTypeOfConstructorMemberReference, getReturnStatementStores, getShouldDefaultTypeVarLocals, getSortedQualifierNames, getStoreAfter, getStoreAfter, getStoreAfter, getStoreBefore, getStoreBefore, getStoreBefore, getSupportedMonotonicTypeQualifiers, getTypeFactoryOfSubchecker, handleCFGViz, methodFromUse, performFlowAnalysis, postDirectSuperTypes, postInit, preProcessClassTree, setRoot, typeVariablesFromUse
adaptGetClassReturnTypeToReceiver, addAliasedAnnotation, addAliasedAnnotation, addAliasedAnnotation, addAliasedAnnotation, addAliasedDeclAnnotation, addAnnotationFromFieldInvariant, addInheritedAnnotation, aliasedAnnotation, annotateInheritedFromClass, annotateInheritedFromClass, checkInvalidOptionsInferSignatures, createAnnotatedTypeFormatter, createAnnotationClassLoader, createAnnotationFormatter, createQualifierHierarchy, createQualifierHierarchy, createQualifierHierarchyFactory, 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
public final AnnotationMirror UNKNOWN
public SameLenAnnotatedTypeFactory(BaseTypeChecker checker)
protected Set<Class<? extends Annotation>> createSupportedTypeQualifiers()
AnnotatedTypeFactory
Subclasses 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 AnnotatedTypeFactory
public QualifierHierarchy createQualifierHierarchy(MultiGraphQualifierHierarchy.MultiGraphFactory factory)
AnnotatedTypeFactory
createQualifierHierarchy
in class AnnotatedTypeFactory
public AnnotatedTypeMirror getAnnotatedTypeLhs(Tree tree)
getAnnotatedTypeLhs
in class GenericAnnotatedTypeFactory<CFValue,CFStore,CFTransfer,CFAnalysis>
tree
- left-hand side of an assignmentlhsTree
public AnnotationMirror getCombinedSameLen(List<String> a1Names, List<String> a2Names)
public AnnotationMirror createCombinedSameLen(FlowExpressions.Receiver rec1, FlowExpressions.Receiver rec2, AnnotationMirror a1, AnnotationMirror a2)
createCombinedSameLen(List, List)
.public AnnotationMirror createCombinedSameLen(List<FlowExpressions.Receiver> receivers, List<AnnotationMirror> annos)
receivers
- a list of receivers representing arrays to be included in the combined
annotationannos
- a list of the current annotations of the receivers. Must be the same length as
receivers.public static boolean shouldUseInAnnotation(FlowExpressions.Receiver receiver)
public TreeAnnotator createTreeAnnotator()
GenericAnnotatedTypeFactory
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));
createTreeAnnotator
in class GenericAnnotatedTypeFactory<CFValue,CFStore,CFTransfer,CFAnalysis>
public AnnotationMirror createSameLen(String... val)