public class SameLenAnnotatedTypeFactory extends BaseAnnotatedTypeFactory
This type factory adds extra expressions to @SameLen annotations when necessary. For example,
if the full version of the type @SameLen({"a","b"})
should include "a", "b", and whatever
is in the @SameLen types for "a" and for "b".
Also, every sequence s should have type @SameLen("s"). However, sometimes the sequence has no @SameLen annotation, and users may write the annotation without the variable itself, as in
@SameLen("b") String a;
rather than the more pedantic
@SameLen({"a", "b"}) String a;
Here are two specific examples where this annotated type factory refines types:
@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.ParameterizedExecutableType
Modifier and Type | Field and Description |
---|---|
AnnotationMirror |
UNKNOWN
The @
SameLenUnknown annotation. |
analysis, cfgVisualizer, defaults, dependentTypesHelper, emptyStore, exceptionalExitStores, flowByDefault, flowResult, flowResultAnalysisCaches, initializationStaticStore, initializationStore, methodInvocationStores, poly, regularExitStores, returnStatementStores, scannedClasses, transfer, treeAnnotator, typeAnnotator
artificialTreeToEnclosingElementMap, checker, elements, fromExpressionTreeCache, fromMemberTreeCache, fromTypeTreeCache, ignoreUninferredTypeArguments, loader, objectGetClass, processingEnv, qualHierarchy, qualifierUpperBounds, reflectionResolver, root, shouldCache, stubTypes, trees, typeArgumentInference, typeFormatter, typeHierarchy, types, typeVarSubstitutor, uid, visitorState
Constructor and Description |
---|
SameLenAnnotatedTypeFactory(BaseTypeChecker checker)
Create a new SameLenAnnotatedTypeFactory.
|
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)
Generates a SameLen that includes each receiver, as well as everything in the annotations2,
if they are SameLen annotations.
|
protected QualifierHierarchy |
createQualifierHierarchy()
Returns the
QualifierHierarchy to be used by this checker. |
AnnotationMirror |
createSameLen(Collection<String> exprs)
Creates a @SameLen annotation whose values are the given strings, from an ordered
collection such as a list or TreeSet in which the strings are in alphabetical order.
|
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)
Returns the type of a left-hand side of an assignment.
|
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 |
mayAppearInSameLen(FlowExpressions.Receiver receiver)
Returns true if the given expression may appear in a @SameLen annotation.
|
createFlowAnalysis
addAnnotationsFromDefaultForType, addCheckedCodeDefaults, addCheckedStandardDefaults, addComputedTypeAnnotations, addComputedTypeAnnotations, addComputedTypeAnnotations, addDefaultAnnotations, addUncheckedStandardDefaults, analyze, applyInferredAnnotations, applyQualifierParameterDefaults, applyQualifierParameterDefaults, checkAndPerformFlowAnalysis, checkForDefaultQualifierInHierarchy, constructorFromUse, constructorFromUsePreSubstitution, createAndInitQualifierDefaults, createCFGVisualizer, createDefaultForTypeAnnotator, createDefaultForUseTypeAnnotator, createDependentTypesHelper, createFlowTransferFunction, createQualifierDefaults, createQualifierPolymorphism, createTypeAnnotator, fromNewClass, getAnnotatedTypeLhsNoTypeVarDefault, getAnnotatedTypeRhsUnaryAssign, getAnnotatedTypeVarargsArray, getAnnotationFromJavaExpressionString, getAnnotationFromReceiver, getAnnotationMirrorFromJavaExpressionString, getCFGVisualizer, getDependentTypesHelper, getEmptyStore, getExceptionalExitStore, getFinalLocalValues, getFirstNodeOfKindForTree, getInferredValueFor, getMethodReturnType, getMethodReturnType, getNodesForTree, getQualifierPolymorphism, getReceiverAndOffsetFromJavaExpressionString, getReceiverFromJavaExpressionString, getRegularExitStore, getResultingTypeOfConstructorMemberReference, getReturnStatementStores, getShouldDefaultTypeVarLocals, getSortedQualifierNames, getStoreAfter, getStoreAfter, getStoreAfter, getStoreBefore, getStoreBefore, getStoreBefore, getSupportedMonotonicTypeQualifiers, getTypeFactoryOfSubchecker, handleCFGViz, methodFromUse, methodFromUsePreSubstitution, performFlowAnalysis, postAnalyze, postAsMemberOf, postDirectSuperTypes, postInit, preProcessClassTree, setRoot, typeVariablesFromUse
adaptGetClassReturnTypeToReceiver, addAliasedAnnotation, addAliasedAnnotation, addAliasedAnnotation, addAliasedAnnotation, addAliasedDeclAnnotation, addAnnotationFromFieldInvariant, addInheritedAnnotation, applyUnboxing, areSameByClass, binaryTreeArgTypes, canonicalAnnotation, checkInvalidOptionsInferSignatures, containsSameByClass, createAnnotatedTypeFormatter, createAnnotationClassLoader, createAnnotationFormatter, createQualifierHierarchyWithMultiGraphFactory, createQualifierUpperBounds, createTypeArgumentInference, createTypeHierarchy, createTypeVariableSubstitutor, declarationFromElement, fromElement, fromElement, fromElement, getAnnotatedNullType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedType, getAnnotatedTypeFormatter, getAnnotatedTypeFromTypeTree, getAnnotationByClass, getAnnotationFormatter, getAnnotationMirror, getAnnotationWithMetaAnnotation, getBoxedType, getBundledTypeQualifiers, getCacheSize, getContext, getCurrentClassTree, getCurrentClassType, getCurrentMethodReceiver, getDeclAnnotation, getDeclAnnotationNoAliases, getDeclAnnotations, getDeclAnnotationWithMetaAnnotation, getDefaultTypeDeclarationBounds, getDummyAssignedTo, getElementUtils, getEnclosingClassOrMethod, getEnclosingElementForArtificialTree, getEnclosingType, getExpressionAndOffset, getFieldInvariantAnnotationTree, getFieldInvariantDeclarationAnnotations, getFieldInvariants, getFnInterfaceFromTree, getFunctionTypeFromTree, getFunctionTypeFromTree, getImplicitReceiverType, getNarrowedPrimitive, getPath, getProcessingEnv, getQualifierHierarchy, getQualifierParameterHierarchies, getQualifierParameterHierarchies, getQualifierUpperBounds, getReceiverType, getSelfType, getStringType, getSupportedTypeQualifierNames, getSupportedTypeQualifiers, getTreeUtils, getTypeArgumentInference, getTypeDeclarationBounds, getTypeHierarchy, getTypeOfExtendsImplements, getTypeVarSubstitutor, getUnboxedType, getUninferredWildcardType, getVisitorState, getWholeProgramInference, getWidenedAnnotations, getWidenedType, hasExplicitNoQualifierParameterInHierarchy, hasExplicitQualifierParameterInHierarchy, hasQualifierParameterInHierarchy, hasQualifierParameterInHierarchy, initializeReflectionResolution, isFromByteCode, isFromStubFile, isSupportedQualifier, isSupportedQualifier, isSupportedQualifier, isWithinConstructor, mergeStubsIntoType, methodFromUse, negateConstant, parseStubFiles, postProcessClassTree, postTypeVarSubstitution, setEnclosingElementForArtificialTree, shouldWarnIfStubRedundantWithBytecode, toAnnotatedType, toString, type, widenToUpperBound
public final AnnotationMirror UNKNOWN
SameLenUnknown
annotation.public SameLenAnnotatedTypeFactory(BaseTypeChecker checker)
protected Set<Class<? extends Annotation>> createSupportedTypeQualifiers()
AnnotatedTypeFactory
Subclasses may override this method 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 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.
To support a different set of annotations than those in the qual subdirectory,
or that have other ElementType
values, see examples below.
In total, there are 5 ways to indicate annotations that are supported by a checker:
This is the default behavior. Simply place those annotations within the qual directory.
Place those annotations within the qual directory, and override AnnotatedTypeFactory.createSupportedTypeQualifiers()
by calling AnnotatedTypeFactory.getBundledTypeQualifiers(Class...)
with a varargs parameter list of the other
annotations. Code example:
@Override protected Set<Class<? extends Annotation>> createSupportedTypeQualifiers() {
return getBundledTypeQualifiers(Regex.class, PartialRegex.class, RegexBottom.class, UnknownRegex.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.getBundledTypeQualifiers(Class...)
must return
a fresh, mutable set
createSupportedTypeQualifiers
in class AnnotatedTypeFactory
protected QualifierHierarchy createQualifierHierarchy()
AnnotatedTypeFactory
QualifierHierarchy
to be used by this checker.
The implementation builds the type qualifier hierarchy for the AnnotatedTypeFactory.getSupportedTypeQualifiers()
using the meta-annotations found in them. The current
implementation returns an instance of NoElementQualifierHierarchy
.
Subclasses must override this method if their qualifiers have elements; the method must
return an implementation of QualifierHierarchy
, such as ElementQualifierHierarchy
.
createQualifierHierarchy
in class AnnotatedTypeFactory
public AnnotatedTypeMirror getAnnotatedTypeLhs(Tree tree)
GenericAnnotatedTypeFactory
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.
getAnnotatedTypeLhs
in class GenericAnnotatedTypeFactory<CFValue,CFStore,CFTransfer,CFAnalysis>
tree
- left-hand side of an assignmentlhsTree
public static boolean mayAppearInSameLen(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
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));
createTreeAnnotator
in class GenericAnnotatedTypeFactory<CFValue,CFStore,CFTransfer,CFAnalysis>
public List<String> getSameLensFromString(String sequenceExpression, Tree tree, TreePath currentPath)
public AnnotationMirror createSameLen(Collection<String> exprs)
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 annotations