public class AnnotatedTypeFactory extends Object implements AnnotationProvider
AnnotatedTypeMirror
. The methods are:
getAnnotatedType(ClassTree)
getAnnotatedType(MethodTree)
getAnnotatedType(Tree)
getAnnotatedTypeFromTypeTree(Tree)
getAnnotatedType(TypeElement)
getAnnotatedType(ExecutableElement)
getAnnotatedType(Element)
addComputedTypeAnnotations(Element, AnnotatedTypeMirror)
and addComputedTypeAnnotations(Tree, AnnotatedTypeMirror)
.Modifier and Type | Class and Description |
---|---|
protected static class |
AnnotatedTypeFactory.InheritedFromClassAnnotator
A singleton utility class for pulling annotations down from a class
type.
|
Modifier and Type | Field and Description |
---|---|
protected BaseTypeChecker |
checker
The checker to use for option handling and resource management.
|
protected Elements |
elements
Utility class for working with
Element s. |
protected Map<Tree,AnnotatedTypeMirror> |
fromTreeCache
Mapping from a Tree to its annotated type; before implicits are applied,
just what the programmer wrote.
|
protected AnnotationClassLoader |
loader
Annotated Type Loader used to load annotation classes via reflective lookup
|
protected ProcessingEnvironment |
processingEnv
The processing environment to use for accessing compiler internals.
|
protected QualifierHierarchy |
qualHierarchy
Represent the annotation relations.
|
protected ReflectionResolver |
reflectionResolver
Object that is used to resolve reflective method calls, if reflection
resolution is turned on.
|
protected @Nullable CompilationUnitTree |
root
Optional! The AST of the source file being operated on.
|
boolean |
shouldCache
Should results be cached?
This means that ATM.deepCopy() will be called.
|
protected Trees |
trees
The
Trees instance to use for tree node path finding. |
protected TypeArgumentInference |
typeArgumentInference
Provides utility method to infer type arguments
|
protected AnnotatedTypeFormatter |
typeFormatter
This formatter is used for converting AnnotatedTypeMirrors to Strings.
|
protected TypeHierarchy |
typeHierarchy
Represent the type relations.
|
protected Types |
types
Utility class for working with
TypeMirror s. |
protected TypeVariableSubstitutor |
typeVarSubstitutor
Provides utility method to substitute arguments for their type variables.
|
int |
uid
Unique ID of the current object; for debugging purposes.
|
protected VisitorState |
visitorState
The state of the visitor.
|
Constructor and Description |
---|
AnnotatedTypeFactory(BaseTypeChecker checker)
Constructs a factory from the given
ProcessingEnvironment
instance and syntax tree root. |
Modifier and Type | Method and Description |
---|---|
protected static void |
adaptGetClassReturnTypeToReceiver(AnnotatedTypeMirror.AnnotatedExecutableType getClassType,
AnnotatedTypeMirror receiverType)
Java special cases the return type of getClass.
|
protected void |
addAliasedAnnotation(Class<?> alias,
AnnotationMirror type)
Add the annotation clazz as an alias for the annotation type.
|
protected void |
addAliasedDeclAnnotation(Class<? extends Annotation> alias,
Class<? extends Annotation> annotation,
AnnotationMirror annotationToUse)
Add the annotation
alias as an alias for the declaration
annotation annotation , where the annotation mirror
annoationToUse will be used instead. |
protected void |
addComputedTypeAnnotations(Element elt,
AnnotatedTypeMirror type)
Adds implicit annotations to a type obtained from a
Element . |
protected void |
addComputedTypeAnnotations(Tree tree,
AnnotatedTypeMirror type)
Adds implicit annotations to a type obtained from a
Tree . |
protected void |
addInheritedAnnotation(AnnotationMirror annotation)
Adds the annotation
annotation in the set of declaration
annotations that should be inherited. |
@Nullable AnnotationMirror |
aliasedAnnotation(AnnotationMirror a)
Returns the canonical annotation for the passed annotation if it is
an alias of a canonical one in the framework.
|
protected void |
annotateInheritedFromClass(AnnotatedTypeMirror type)
Adds annotations to the type based on the annotations from its class
type if and only if no annotations are already present on the type.
|
protected void |
annotateInheritedFromClass(AnnotatedTypeMirror type,
Set<AnnotationMirror> fromClass)
Callback to determine what to do with the annotations from a class declaration.
|
protected void |
checkInvalidOptionsInferSignatures()
This method is called only when -Ainfer is passed as an option.
|
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 AnnotationFormatter |
createAnnotationFormatter() |
protected QualifierHierarchy |
createQualifierHierarchy()
Returns the type qualifier hierarchy graph to be used by this processor.
|
protected static QualifierHierarchy |
createQualifierHierarchy(Elements elements,
Set<Class<? extends Annotation>> supportedTypeQualifiers,
MultiGraphQualifierHierarchy.MultiGraphFactory factory)
Returns the type qualifier hierarchy graph for a given set of type qualifiers and a factory.
|
QualifierHierarchy |
createQualifierHierarchy(MultiGraphQualifierHierarchy.MultiGraphFactory factory)
Factory method to easily change what QualifierHierarchy is
created.
|
protected MultiGraphQualifierHierarchy.MultiGraphFactory |
createQualifierHierarchyFactory()
Factory method to easily change what Factory is used to
create a QualifierHierarchy.
|
protected Set<Class<? extends Annotation>> |
createSupportedTypeQualifiers()
Returns a mutable set of annotation classes that are supported by a checker
|
protected TypeArgumentInference |
createTypeArgumentInference()
TypeArgumentInference infers the method type arguments when
they are not explicitly written.
|
protected TypeHierarchy |
createTypeHierarchy()
Creates the type subtyping checker using the current type qualifier
hierarchy.
|
protected TypeVariableSubstitutor |
createTypeVariableSubstitutor()
TypeVariableSubstitutor provides a method to replace type parameters with
their arguments.
|
Tree |
declarationFromElement(Element elt)
Gets the declaration tree for the element, if the source is available.
|
AnnotatedTypeMirror |
fromElement(Element elt)
Creates an AnnotatedTypeMirror for
elt that includes:
annotations explicitly written on the element and annotations from stub files |
AnnotatedTypeMirror.AnnotatedExecutableType |
fromElement(ExecutableElement elt) |
AnnotatedTypeMirror.AnnotatedDeclaredType |
fromElement(TypeElement elt) |
AnnotatedTypeMirror.AnnotatedDeclaredType |
fromNewClass(NewClassTree newClassTree)
Creates an AnnotatedDeclaredType for a NewClassTree.
|
AnnotatedTypeMirror.AnnotatedNullType |
getAnnotatedNullType(Set<? extends AnnotationMirror> annotations)
Creates and returns an AnnotatedNullType qualified with
annotations . |
AnnotatedTypeMirror.AnnotatedDeclaredType |
getAnnotatedType(ClassTree tree) |
AnnotatedTypeMirror |
getAnnotatedType(Element elt)
Returns an AnnotatedTypeMirror representing the annotated type of
elt . |
AnnotatedTypeMirror.AnnotatedExecutableType |
getAnnotatedType(ExecutableElement elt) |
AnnotatedTypeMirror.AnnotatedExecutableType |
getAnnotatedType(MethodTree tree) |
AnnotatedTypeMirror.AnnotatedArrayType |
getAnnotatedType(NewArrayTree tree) |
AnnotatedTypeMirror.AnnotatedDeclaredType |
getAnnotatedType(NewClassTree tree) |
AnnotatedTypeMirror |
getAnnotatedType(Tree tree)
Returns an AnnotatedTypeMirror representing the annotated type of
tree . |
AnnotatedTypeMirror.AnnotatedDeclaredType |
getAnnotatedType(TypeElement elt) |
AnnotatedTypeMirror |
getAnnotatedTypeFromTypeTree(Tree tree)
Determines the annotated type from a type in tree form.
|
AnnotationFormatter |
getAnnotationFormatter() |
AnnotationMirror |
getAnnotationMirror(Tree tree,
Class<? extends Annotation> target)
Return the annotation on
tree that has the class
target . |
List<Pair<AnnotationMirror,AnnotationMirror>> |
getAnnotationWithMetaAnnotation(Element element,
Class<? extends Annotation> metaAnnotation)
Returns a list of all annotations used to annotate this element,
which have a meta-annotation (i.e., an annotation on that annotation)
with class
metaAnnotation . |
AnnotatedTypeMirror.AnnotatedDeclaredType |
getBoxedType(AnnotatedTypeMirror.AnnotatedPrimitiveType type)
Returns the annotated boxed type of the given primitive type.
|
protected Set<Class<? extends Annotation>> |
getBundledTypeQualifiersWithoutPolyAll(Class<? extends Annotation>... explicitlyListedAnnotations)
Loads all annotations contained in the qual directory of a checker via
reflection, and an explicit list of annotations to the set of annotation
classes.
|
protected Set<Class<? extends Annotation>> |
getBundledTypeQualifiersWithPolyAll(Class<? extends Annotation>... explicitlyListedAnnotations)
Loads all annotations contained in the qual directory of a checker via
reflection, and adds
PolyAll and an explicit array of annotations
to the set of annotation classes. |
CFContext |
getContext()
Accessor for the
CFContext . |
protected ClassTree |
getCurrentClassTree(Tree tree)
Returns the current class type being visited by the visitor.
|
protected AnnotatedTypeMirror.AnnotatedDeclaredType |
getCurrentClassType(Tree tree) |
protected @Nullable AnnotatedTypeMirror.AnnotatedDeclaredType |
getCurrentMethodReceiver(Tree tree)
Returns the receiver type of the current method being visited, and
returns null if the visited tree is not within a method or if that
method has no receiver (e.g.
|
AnnotationMirror |
getDeclAnnotation(Element elt,
Class<? extends Annotation> anno)
Returns the actual annotation mirror used to annotate this element,
whose name equals the passed annotation class, if one exists, or null otherwise.
|
AnnotationMirror |
getDeclAnnotationNoAliases(Element elt,
Class<? extends Annotation> anno)
Returns the actual annotation mirror used to annotate this element,
whose name equals the passed annotation class, if one exists, or null otherwise.
|
Set<AnnotationMirror> |
getDeclAnnotations(Element elt)
Returns all of the actual annotation mirrors used to annotate this element
(includes stub files and declaration annotations from overridden methods).
|
List<Pair<AnnotationMirror,AnnotationMirror>> |
getDeclAnnotationWithMetaAnnotation(Element element,
Class<? extends Annotation> metaAnnotation)
Returns a list of all declaration annotations used to annotate this element,
which have a meta-annotation (i.e., an annotation on that annotation)
with class
metaAnnotation . |
Elements |
getElementUtils()
Accessor for the element utilities.
|
Element |
getEnclosingMethod(Tree node)
Gets the
Element representing the declaration of the
method enclosing a tree node. |
AnnotatedTypeMirror.AnnotatedDeclaredType |
getEnclosingType(TypeElement element,
Tree tree)
Determine the type of the most enclosing class of the given tree that
is a subtype of the given element.
|
Pair<AnnotatedTypeMirror.AnnotatedDeclaredType,AnnotatedTypeMirror.AnnotatedExecutableType> |
getFnInterfaceFromTree(LambdaExpressionTree tree) |
Pair<AnnotatedTypeMirror.AnnotatedDeclaredType,AnnotatedTypeMirror.AnnotatedExecutableType> |
getFnInterfaceFromTree(MemberReferenceTree tree) |
protected AnnotatedTypeMirror.AnnotatedDeclaredType |
getImplicitReceiverType(ExpressionTree tree)
Return the implicit receiver type of an expression 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 . |
AnnotatedTypeMirror.AnnotatedPrimitiveType |
getNarrowedPrimitive(AnnotatedTypeMirror.AnnotatedPrimitiveType type,
TypeMirror narrowedTypeMirror)
Returns AnnotatedPrimitiveType with underlying type
narrowedTypeMirror and
annotations copied from type . |
TreePath |
getPath(Tree node)
Gets the path for the given
Tree under the current root by
checking from the visitor's current path, and only using
Trees.getPath(CompilationUnitTree, Tree) (which is much slower)
only if node is not found on the current path. |
ProcessingEnvironment |
getProcessingEnv()
Accessor for the processing environment.
|
QualifierHierarchy |
getQualifierHierarchy()
Returns the type qualifier hierarchy graph to be used by this processor.
|
AnnotatedTypeMirror |
getReceiverType(ExpressionTree expression)
Returns the receiver type of the expression tree, or null if it does not exist.
|
AnnotatedTypeMirror.AnnotatedDeclaredType |
getSelfType(Tree tree)
Returns the type of
this in the current location, which can
be used if this has a special semantics (e.g. |
AnnotatedTypeMirror.AnnotatedDeclaredType |
getStringType(AnnotatedTypeMirror type)
Returns AnnotatedDeclaredType with underlying type String and annotations copied from type.
|
Set<Class<? extends Annotation>> |
getSupportedTypeQualifiers()
Returns an immutable set of the type qualifiers supported by this
checker.
|
Trees |
getTreeUtils()
Accessor for the tree utilities.
|
TypeArgumentInference |
getTypeArgumentInference() |
TypeHierarchy |
getTypeHierarchy() |
TypeVariableSubstitutor |
getTypeVarSubstitutor() |
AnnotatedTypeMirror.AnnotatedPrimitiveType |
getUnboxedType(AnnotatedTypeMirror.AnnotatedDeclaredType type)
returns the annotated primitive type of the given declared type
if it is a boxed declared type.
|
AnnotatedTypeMirror.AnnotatedWildcardType |
getUninferredWildcardType(AnnotatedTypeMirror.AnnotatedTypeVariable typeVar)
This method is a hack to use when a method type argument
could not be inferred automatically or if a raw type is used.
|
VisitorState |
getVisitorState()
Returns the VisitorState instance used by the factory to infer types
|
WholeProgramInference |
getWholeProgramInference()
Returns the WholeProgramInference instance.
|
protected void |
initilizeReflectionResolution() |
boolean |
isAnyEnclosingThisDeref(ExpressionTree tree)
Does this expression have (the innermost or an outer) "this" as receiver?
Note that the receiver can be either explicit or implicit.
|
boolean |
isFromByteCode(Element element)
Returns true if the element is from byte code
and the if the element did not appear in a stub file
(Currently only works for methods, constructors, and fields)
|
boolean |
isFromStubFile(Element element)
Returns true if the element appears in a stub file
(Currently only works for methods, constructors, and fields)
|
boolean |
isMostEnclosingThisDeref(ExpressionTree tree)
Determine whether the tree dereferences the most enclosing "this" object.
|
boolean |
isSupportedQualifier(@Nullable AnnotationMirror a)
Determines whether the given annotation is a part of the type system
under which this type factory operates.
|
protected boolean |
isWithinConstructor(Tree tree) |
Pair<AnnotatedTypeMirror.AnnotatedExecutableType,List<AnnotatedTypeMirror>> |
methodFromUse(ExpressionTree tree,
ExecutableElement methodElt,
AnnotatedTypeMirror receiverType) |
Pair<AnnotatedTypeMirror.AnnotatedExecutableType,List<AnnotatedTypeMirror>> |
methodFromUse(MethodInvocationTree tree)
Determines the type of the invoked method based on the passed method
invocation tree.
|
protected void |
parseStubFiles()
Parses the stub files in the following order:
1. |
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 |
postProcessClassTree(ClassTree tree)
Called by
BaseTypeVisitor.visitClass(ClassTree, Void) after the ClassTree has been
type checked. |
void |
postTypeVarSubstitution(AnnotatedTypeMirror.AnnotatedTypeVariable varDecl,
AnnotatedTypeMirror.AnnotatedTypeVariable varUse,
AnnotatedTypeMirror value)
A callback method for the AnnotatedTypeFactory subtypes to customize
AnnotatedTypeMirror.substitute().
|
void |
preProcessClassTree(ClassTree classTree)
Called by
BaseTypeVisitor.visitClass(ClassTree, Void) before the classTree is type
checked. |
void |
setPathHack(Tree node,
Element enclosing) |
void |
setRoot(@Nullable CompilationUnitTree root) |
protected AnnotatedTypeMirror |
toAnnotatedType(TypeMirror t,
boolean declaration)
A convenience method that converts a
TypeMirror to an empty AnnotatedTypeMirror using AnnotatedTypeMirror.createType(javax.lang.model.type.TypeMirror, org.checkerframework.framework.type.AnnotatedTypeFactory, boolean) . |
String |
toString() |
protected AnnotatedTypeMirror |
type(Tree node)
Determines an empty annotated type of the given tree.
|
List<AnnotatedTypeParameterBounds> |
typeVariablesFromUse(AnnotatedTypeMirror.AnnotatedDeclaredType type,
TypeElement element)
Adapt the upper bounds of the type variables of a class relative
to the type instantiation.
|
AnnotatedTypeMirror |
widenToUpperBound(AnnotatedTypeMirror annotatedTypeMirror,
AnnotatedTypeMirror.AnnotatedWildcardType wildcard)
If
wildcard 's upper bound is a super type of annotatedTypeMirror ,
this method returns an AnnotatedTypeMirror with the same qualifiers as annotatedTypeMirror , but
the underlying Java type is the the most specific base type of annotatedTypeMirror whose erasure type
is equivalent to the upper bound of wildcard . |
protected @Nullable CompilationUnitTree root
protected final ProcessingEnvironment processingEnv
protected final Types types
TypeMirror
s.protected final VisitorState visitorState
protected QualifierHierarchy qualHierarchy
protected TypeHierarchy typeHierarchy
protected final AnnotatedTypeFormatter typeFormatter
protected TypeVariableSubstitutor typeVarSubstitutor
protected TypeArgumentInference typeArgumentInference
protected final BaseTypeChecker checker
public final int uid
protected ReflectionResolver reflectionResolver
protected AnnotationClassLoader loader
public boolean shouldCache
protected final Map<Tree,AnnotatedTypeMirror> fromTreeCache
public AnnotatedTypeFactory(BaseTypeChecker checker)
ProcessingEnvironment
instance and syntax tree root. (These parameters are required so that
the factory may conduct the appropriate annotation-gathering analyses on
certain tree types.)
Root can be null
if the factory does not operate on trees.
A subclass must call postInit at the end of its constructor. postInit must be the last call in the constructor or else types from stub files may not be created as expected.
checker
- the SourceChecker
to which this factory belongsIllegalArgumentException
- if either argument is null
protected void checkInvalidOptionsInferSignatures()
protected void postInit()
public WholeProgramInference getWholeProgramInference()
protected void initilizeReflectionResolution()
public void setRoot(@Nullable CompilationUnitTree root)
@SideEffectFree public String toString()
protected MultiGraphQualifierHierarchy.MultiGraphFactory createQualifierHierarchyFactory()
public QualifierHierarchy createQualifierHierarchy(MultiGraphQualifierHierarchy.MultiGraphFactory factory)
protected QualifierHierarchy createQualifierHierarchy()
The implementation builds the type qualifier hierarchy for the
getSupportedTypeQualifiers()
using the
meta-annotations found in them. The current implementation returns an
instance of GraphQualifierHierarchy
.
Subclasses may override this method to express any relationships that cannot be inferred using meta-annotations (e.g. due to lack of meta-annotations).
protected static QualifierHierarchy createQualifierHierarchy(Elements elements, Set<Class<? extends Annotation>> supportedTypeQualifiers, MultiGraphQualifierHierarchy.MultiGraphFactory factory)
The implementation builds the type qualifier hierarchy for the
supportedTypeQualifiers
. The current implementation returns an
instance of GraphQualifierHierarchy
.
public final QualifierHierarchy getQualifierHierarchy()
QualifierHierarchy
for this checkercreateQualifierHierarchy()
protected TypeHierarchy createTypeHierarchy()
Subclasses may override this method to specify new type-checking rules beyond the typical java subtyping rules.
public final TypeHierarchy getTypeHierarchy()
protected TypeVariableSubstitutor createTypeVariableSubstitutor()
public TypeVariableSubstitutor getTypeVarSubstitutor()
protected TypeArgumentInference createTypeArgumentInference()
public TypeArgumentInference getTypeArgumentInference()
protected Set<Class<? extends Annotation>> createSupportedTypeQualifiers()
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
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
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
createSupportedTypeQualifiers()
by calling
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
createSupportedTypeQualifiers()
by calling
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
createSupportedTypeQualifiers()
by calling
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);
}
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
createSupportedTypeQualifiers()
must be a fresh, mutable
set. The methods
getBundledTypeQualifiersWithoutPolyAll(Class...)
and
getBundledTypeQualifiersWithPolyAll(Class...)
each
must return a fresh, mutable set
@SafeVarargs protected final Set<Class<? extends Annotation>> getBundledTypeQualifiersWithPolyAll(Class<? extends Annotation>... explicitlyListedAnnotations)
PolyAll
and an explicit array of annotations
to the set of annotation classes.
This method can be called in the overridden versions of
createSupportedTypeQualifiers()
in each checker.
explicitlyListedAnnotations
- a varargs array of explicitly listed annotation classes to be
added to the returned set. For example, it is used frequently
to add Bottom qualifiers.PolyAll
.@SafeVarargs protected final Set<Class<? extends Annotation>> getBundledTypeQualifiersWithoutPolyAll(Class<? extends Annotation>... explicitlyListedAnnotations)
This method can be called in the overridden versions of
createSupportedTypeQualifiers()
in each checker.
explicitlyListedAnnotations
- a varargs array of explicitly listed annotation classes to be
added to the returned set. For example, it is used frequently
to add Bottom qualifiers.protected AnnotatedTypeFormatter createAnnotatedTypeFormatter()
protected AnnotationFormatter createAnnotationFormatter()
public AnnotationFormatter getAnnotationFormatter()
public final Set<Class<? extends Annotation>> getSupportedTypeQualifiers()
Subclasses cannot override this method; they should override
createSupportedTypeQualifiers
instead.
createSupportedTypeQualifiers()
public AnnotatedTypeMirror getAnnotatedType(Element elt)
elt
.elt
- the elementelt
public AnnotationMirror getAnnotationMirror(Tree tree, Class<? extends Annotation> target)
AnnotationProvider
tree
that has the class
target
. If no annotation for the given target class exists,
the result is null
getAnnotationMirror
in interface AnnotationProvider
tree
- The tree of which the annotation is returnedtarget
- The class of the annotationpublic AnnotatedTypeMirror getAnnotatedType(Tree tree)
tree
.
tree
- the AST nodetree
public void preProcessClassTree(ClassTree classTree)
BaseTypeVisitor.visitClass(ClassTree, Void)
before the classTree is type
checked.classTree
- ClassTree on which to perfrom preprocessingpublic void postProcessClassTree(ClassTree tree)
BaseTypeVisitor.visitClass(ClassTree, Void)
after the ClassTree has been
type checked.
The default implementation uses this to store the defaulted AnnotatedTypeMirrors and inherited declaration annotations back into the corresponding Elements. Subclasses might want to override this method if storing defaulted types is not desirable.
public AnnotatedTypeMirror getAnnotatedTypeFromTypeTree(Tree tree)
Note that we cannot decide from a Tree whether it is a type use or an expression. TreeUtils.isTypeTree is only an under-approximation. For example, an identifier can be either a type or an expression.
tree
- the type treepublic AnnotatedTypeMirror fromElement(Element elt)
elt
that includes:
annotations explicitly written on the element and annotations from stub fileselt
- the elementprotected void addComputedTypeAnnotations(Tree tree, AnnotatedTypeMirror type)
Tree
. By
default, this method does nothing. Subclasses should use this method to
implement implicit annotations specific to their type systems.tree
- an AST nodetype
- the type obtained from tree
protected void addComputedTypeAnnotations(Element elt, AnnotatedTypeMirror type)
Element
. By
default, this method does nothing. Subclasses should use this method to
implement implicit annotations specific to their type systems.elt
- an elementtype
- the type obtained from elt
protected void postDirectSuperTypes(AnnotatedTypeMirror type, List<? extends AnnotatedTypeMirror> supertypes)
The default provided implementation adds type
annotations to
supertypes
. This allows the type
and its supertypes
to have the qualifiers.
type
- the type whose supertypes are desiredsupertypes
- the supertypes as specified by the base AnnotatedTypeFactorypublic void postAsMemberOf(AnnotatedTypeMirror type, AnnotatedTypeMirror owner, Element element)
type
- the annotated type of the elementowner
- the annotated type of the receiver of the accessing treeelement
- the element of the field or methodpublic void postTypeVarSubstitution(AnnotatedTypeMirror.AnnotatedTypeVariable varDecl, AnnotatedTypeMirror.AnnotatedTypeVariable varUse, AnnotatedTypeMirror value)
varDecl
- a declaration of a type variablevarUse
- a use of the same type variablevalue
- the new type to substitute in for the type variablepublic List<AnnotatedTypeParameterBounds> typeVariablesFromUse(AnnotatedTypeMirror.AnnotatedDeclaredType type, TypeElement element)
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.
type
- the use of the typeelement
- the corresponding elementprotected void annotateInheritedFromClass(AnnotatedTypeMirror type)
The class type is found using fromElement(Element)
type
- the type for which class annotations will be inherited if
there are no annotations already presentprotected void annotateInheritedFromClass(AnnotatedTypeMirror type, Set<AnnotationMirror> fromClass)
public AnnotatedTypeMirror.AnnotatedNullType getAnnotatedNullType(Set<? extends AnnotationMirror> annotations)
annotations
.annotations
- set of AnnotationMirrors to qualify the returned type withannotations
protected AnnotatedTypeMirror.AnnotatedDeclaredType getImplicitReceiverType(ExpressionTree tree)
The result is null for expressions that don't have a receiver, e.g. for a local variable or method parameter access.
tree
- the expression that might have an implicit receiverpublic final boolean isMostEnclosingThisDeref(ExpressionTree tree)
tree
- the tree to checkpublic final boolean isAnyEnclosingThisDeref(ExpressionTree tree)
tree
- the tree to testpublic AnnotatedTypeMirror.AnnotatedDeclaredType getSelfType(Tree tree)
this
in the current location, which can
be used if this
has a special semantics (e.g. this
is non-null).
The parameter is an arbitrary tree and does not have to mention "this", neither explicitly nor implicitly. This method should be overridden for type-system specific behavior. TODO: in 1.8.2, handle all receiver type annotations. TODO: handle enclosing classes correctly.
public AnnotatedTypeMirror.AnnotatedDeclaredType getEnclosingType(TypeElement element, Tree tree)
public final AnnotatedTypeMirror getReceiverType(ExpressionTree expression)
The only trees that could potentially have a receiver are:
expression
- the expression for which to determine the receiver typepublic Pair<AnnotatedTypeMirror.AnnotatedExecutableType,List<AnnotatedTypeMirror>> methodFromUse(MethodInvocationTree tree)
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 constructorFromUse(NewClassTree)
is only used for a constructor
invocation in a "new" expression.
tree
- the method invocation treepublic Pair<AnnotatedTypeMirror.AnnotatedExecutableType,List<AnnotatedTypeMirror>> methodFromUse(ExpressionTree tree, ExecutableElement methodElt, AnnotatedTypeMirror receiverType)
protected static void adaptGetClassReturnTypeToReceiver(AnnotatedTypeMirror.AnnotatedExecutableType getClassType, AnnotatedTypeMirror receiverType)
Class<?>
,
the compiler special cases this return type and changes the bound of the type argument to the
erasure of the receiver type. e.g.,
x.getClass() has the type Class< ? extends erasure_of_x >
someInteger.getClass() has the type Class< ? extends Integer >
getClassType
- this must be a type representing a call to Object.getClass otherwise
a runtime exception will be thrownreceiverType
- the receiver type of the method invocation (not the declared receiver type)public Pair<AnnotatedTypeMirror.AnnotatedExecutableType,List<AnnotatedTypeMirror>> constructorFromUse(NewClassTree tree)
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 methodFromUse(com.sun.source.tree.MethodInvocationTree)
. This method only handles constructor invocations
in a "new" expression.
tree
- the constructor invocation treepublic AnnotatedTypeMirror getMethodReturnType(MethodTree m)
m
.public AnnotatedTypeMirror getMethodReturnType(MethodTree m, ReturnTree r)
m
at the return statement r
.public final AnnotatedTypeMirror.AnnotatedDeclaredType fromNewClass(NewClassTree newClassTree)
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.
newClassTree
- NewClassTreepublic AnnotatedTypeMirror.AnnotatedDeclaredType getBoxedType(AnnotatedTypeMirror.AnnotatedPrimitiveType type)
Subclasses may override this method safely to override this behavior.
type
- the primitive typepublic AnnotatedTypeMirror.AnnotatedPrimitiveType getUnboxedType(AnnotatedTypeMirror.AnnotatedDeclaredType type) throws IllegalArgumentException
The returned type would have the annotations on the given type and nothing else.
type
- the declared typeIllegalArgumentException
- if the type given has no unbox conversionpublic AnnotatedTypeMirror.AnnotatedDeclaredType getStringType(AnnotatedTypeMirror type)
type
- type to convert to Stringpublic AnnotatedTypeMirror.AnnotatedPrimitiveType getNarrowedPrimitive(AnnotatedTypeMirror.AnnotatedPrimitiveType type, TypeMirror narrowedTypeMirror)
narrowedTypeMirror
and
annotations copied from type
.
Currently this method is called only for primitives that are narrowed at assignments from
literal ints, for example, byte b = 1;
. All other narrowing conversions happen at
typecasts.type
- type to narrow.narrowedTypeMirror
- underlying type for the returned type mirrortype
to narrowedTypeMirror
public VisitorState getVisitorState()
public final AnnotatedTypeMirror.AnnotatedDeclaredType getAnnotatedType(ClassTree tree)
getAnnotatedType(Tree)
public final AnnotatedTypeMirror.AnnotatedDeclaredType getAnnotatedType(NewClassTree tree)
getAnnotatedType(Tree)
public final AnnotatedTypeMirror.AnnotatedArrayType getAnnotatedType(NewArrayTree tree)
getAnnotatedType(Tree)
public final AnnotatedTypeMirror.AnnotatedExecutableType getAnnotatedType(MethodTree tree)
getAnnotatedType(Tree)
public final AnnotatedTypeMirror.AnnotatedDeclaredType getAnnotatedType(TypeElement elt)
getAnnotatedType(Element)
public final AnnotatedTypeMirror.AnnotatedExecutableType getAnnotatedType(ExecutableElement elt)
getAnnotatedType(Element)
public final AnnotatedTypeMirror.AnnotatedDeclaredType fromElement(TypeElement elt)
fromElement(Element)
public final AnnotatedTypeMirror.AnnotatedExecutableType fromElement(ExecutableElement elt)
fromElement(Element)
public boolean isSupportedQualifier(@Nullable AnnotationMirror a)
a
- any annotationprotected void addAliasedAnnotation(Class<?> alias, AnnotationMirror type)
public @Nullable AnnotationMirror aliasedAnnotation(AnnotationMirror a)
Returns an aliased type of the current one
a
- the qualifier to check for an aliasprotected void addAliasedDeclAnnotation(Class<? extends Annotation> alias, Class<? extends Annotation> annotation, AnnotationMirror annotationToUse)
alias
as an alias for the declaration
annotation annotation
, where the annotation mirror
annoationToUse
will be used instead. If multiple calls are made
with the same annotation
, then the anontationToUse
must
be the same.protected void addInheritedAnnotation(AnnotationMirror annotation)
annotation
in the set of declaration
annotations that should be inherited. A declaration annotation
will be inherited if it is in this list, or if it has the
meta-annotation @InheritedAnnotation.
The meta-annotation @InheritedAnnotation should be used instead of this
method, if possible.protected final AnnotatedTypeMirror toAnnotatedType(TypeMirror t, boolean declaration)
TypeMirror
to an empty AnnotatedTypeMirror
using AnnotatedTypeMirror.createType(javax.lang.model.type.TypeMirror, org.checkerframework.framework.type.AnnotatedTypeFactory, boolean)
.t
- the TypeMirror
declaration
- true if the result should be marked as a type declarationAnnotatedTypeMirror
that has t
as its
underlying typeprotected final AnnotatedTypeMirror type(Tree node)
TypeMirror
for the tree and converts that into an
AnnotatedTypeMirror
, but does not add any annotations to the
result.
Most users will want to use getAnnotatedType instead; this method is mostly for internal use.
node
- the tree to analyzenode
, without any annotationspublic final Tree declarationFromElement(Element elt)
elt
- an elementprotected final ClassTree getCurrentClassTree(Tree tree)
protected final AnnotatedTypeMirror.AnnotatedDeclaredType getCurrentClassType(Tree tree)
protected final @Nullable AnnotatedTypeMirror.AnnotatedDeclaredType getCurrentMethodReceiver(Tree tree)
The method uses the parameter only if the most enclosing method cannot be found directly.
protected final boolean isWithinConstructor(Tree tree)
public final TreePath getPath(Tree node)
Tree
under the current root by
checking from the visitor's current path, and only using
Trees.getPath(CompilationUnitTree, Tree)
(which is much slower)
only if node
is not found on the current path.
Note that the given Tree has to be within the current compilation unit, otherwise null will be returned.
node
- the Tree
to get the path fornode
under the current rootprotected void parseStubFiles()
If a type is annotated with a qualifier from the same hierarchy in more than one stub file, the qualifier in the last stub file is applied.
Sets typesFromStubFiles and declAnnosFromStubFiles by side effect, just before returning.
public final AnnotationMirror getDeclAnnotation(Element elt, Class<? extends Annotation> anno)
getDeclAnnotation
in interface AnnotationProvider
elt
- the element to retrieve the declaration annotation fromanno
- annotation classgetDeclAnnotationNoAliases(javax.lang.model.element.Element, java.lang.Class<? extends java.lang.annotation.Annotation>)
public final AnnotationMirror getDeclAnnotationNoAliases(Element elt, Class<? extends Annotation> anno)
Call this method from a checker that needs to alias annotations for one purpose
and not for another. For example, in the Lock Checker, @LockingFree
and
@ReleasesNoLocks
are both aliases of @SideEffectFree
since they are
all considered side-effect-free with regard to the set of locks held before
and after the method call. However, a synchronized
block is permitted inside
a @ReleasesNoLocks
method but not inside a @LockingFree
or
@SideEffectFree
method.
elt
- the element to retrieve the declaration annotation fromanno
- annotation classgetDeclAnnotation(javax.lang.model.element.Element, java.lang.Class<? extends java.lang.annotation.Annotation>)
public boolean isFromStubFile(Element element)
public boolean isFromByteCode(Element element)
public Set<AnnotationMirror> getDeclAnnotations(Element elt)
elt
- The element for which to determine annotations.public List<Pair<AnnotationMirror,AnnotationMirror>> getDeclAnnotationWithMetaAnnotation(Element element, Class<? extends Annotation> metaAnnotation)
metaAnnotation
.element
- The element for which to determine annotations.metaAnnotation
- The meta-annotation that needs to be present.(anno, metaAnno)
where anno
is
the annotation mirror at element
, and metaAnno
is
the annotation mirror used to annotate anno
.public List<Pair<AnnotationMirror,AnnotationMirror>> getAnnotationWithMetaAnnotation(Element element, Class<? extends Annotation> metaAnnotation)
metaAnnotation
.element
- The element at which to look for annotations.metaAnnotation
- The meta-annotation that needs to be present.(anno, metaAnno)
where anno
is
the annotation mirror at element
, and metaAnno
is
the annotation mirror used to annotate anno
.public AnnotatedTypeMirror.AnnotatedWildcardType getUninferredWildcardType(AnnotatedTypeMirror.AnnotatedTypeVariable typeVar)
public AnnotatedTypeMirror widenToUpperBound(AnnotatedTypeMirror annotatedTypeMirror, AnnotatedTypeMirror.AnnotatedWildcardType wildcard)
wildcard
's upper bound is a super type of annotatedTypeMirror
,
this method returns an AnnotatedTypeMirror with the same qualifiers as annotatedTypeMirror
, but
the underlying Java type is the the most specific base type of annotatedTypeMirror
whose erasure type
is equivalent to the upper bound of wildcard
.
Otherwise, returns annotatedTypeMirror
unmodified.
For example:
wildcard := @NonNull ? extends @NonNull Object annotatedTypeMirror := @Nullable String widenToUpperBound(annotatedTypeMirror, wildcard) returns @Nullable ObjectThis method is needed because, the Java compiler allows wildcards to have upper bounds above the type variable upper bounds for which they are type arguments. For example, given the following parametric type:
class MyClass<T extends Number>
the following is legal:
MyClass<? extends Object>
This is sound because in Java the wildcard is capture converted to:
CAP#1 extends Number from capture of ? extends Object
.
Because the Checker Framework does not implement capture conversion, wildcard upper bounds may cause spurious errors in subtyping checks. This method prevents those errors by widening the upper bound of the type parameter.
This method widens the underlying Java type of the upper bound of the type parameter rather than narrowing the bound of the wildcard in order to avoid issuing an error with an upper bound that is not in source code.
The widened type should only be used for typing checks that require it. Using the widened type elsewhere would cause confusing error messages with types not in the source code.
annotatedTypeMirror
- AnnotatedTypeMirror to widenwildcard
- AnnotatedWildcardType whose upper bound is used to widenannotatedTypeMirror
widen to the upper bound of wildcard
public Pair<AnnotatedTypeMirror.AnnotatedDeclaredType,AnnotatedTypeMirror.AnnotatedExecutableType> getFnInterfaceFromTree(MemberReferenceTree tree)
public Pair<AnnotatedTypeMirror.AnnotatedDeclaredType,AnnotatedTypeMirror.AnnotatedExecutableType> getFnInterfaceFromTree(LambdaExpressionTree tree)
public Elements getElementUtils()
public Trees getTreeUtils()
public ProcessingEnvironment getProcessingEnv()