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)
Type system checker writers may need to subclass this class, to add implicit and default
qualifiers according to the type system semantics. Subclasses should especially override addComputedTypeAnnotations(Element, AnnotatedTypeMirror)
and addComputedTypeAnnotations(Tree, AnnotatedTypeMirror)
. (Also, addDefaultAnnotations(AnnotatedTypeMirror)
adds annotations, but that method is a work around
for Issue 979.)
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.
|
boolean |
ignoreUninferredTypeArguments
Whether to ignore uninferred type arguments.
|
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 void |
adaptGetClassReturnTypeToReceiver(AnnotatedTypeMirror.AnnotatedExecutableType getClassType,
AnnotatedTypeMirror receiverType)
Java special-cases the return type of
getClass() . |
protected void |
addAliasedAnnotation(Class<?> aliasClass,
AnnotationMirror type)
Adds the annotation
aliasClass as an alias for the canonical annotation type
that will be used by the Checker Framework in the alias's place. |
protected void |
addAliasedAnnotation(Class<?> aliasClass,
AnnotationMirror type,
boolean copyElements,
String... ignorableElements)
Adds the annotation
aliasClass as an alias for the canonical annotation type
that will be used by the Checker Framework in the alias's place. |
protected void |
addAliasedAnnotation(String aliasName,
AnnotationMirror type)
Adds the annotation, whose fully-qualified name is given by
aliasName , as an alias
for the canonical annotation type that will be used by the Checker Framework in the
alias's place. |
protected void |
addAliasedAnnotation(String aliasName,
AnnotationMirror type,
boolean copyElements,
String... ignorableElements)
Adds the annotation, whose fully-qualified name is given by
aliasName , as an alias
for the canonical annotation type that will be used by the Checker Framework in the
alias's place. |
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 |
addAnnotationFromFieldInvariant(AnnotatedTypeMirror type,
AnnotatedTypeMirror accessedVia,
VariableElement field)
Adds the qualifier specified by a field invariant for
field to type . |
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 |
addDefaultAnnotations(AnnotatedTypeMirror type)
Adds default annotations to
type . |
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) |
AnnotatedTypeFormatter |
getAnnotatedTypeFormatter() |
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 , if a polymorphic type qualifier exists, and an explicit array of annotations
to the set of annotation classes. |
protected int |
getCacheSize()
Returns the int supplied to the checker via the atfCacheSize option or the default cache
size.
|
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.
|
AnnotationTree |
getFieldInvariantAnnotationTree(List<? extends AnnotationTree> annoTrees)
Returns the AnnotationTree which is a use of one of the field invariant annotations (as
specified via
getFieldInvariantDeclarationAnnotations() . |
protected Set<Class<? extends Annotation>> |
getFieldInvariantDeclarationAnnotations()
Returns the set of classes of field invariant annotations.
|
FieldInvariants |
getFieldInvariants(TypeElement element)
Returns the field invariants for the given class.
|
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)
Returns a wildcard type to be used as a type argument when the correct type could not be
inferred.
|
VisitorState |
getVisitorState()
Returns the VisitorState instance used by the factory to infer types
|
WholeProgramInference |
getWholeProgramInference()
Returns the WholeProgramInference instance.
|
protected void |
initializeReflectionResolution() |
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 bytecode 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:
jdk.astub in the same directory as the checker, if it exists and ignorejdkastub option is not supplied flow.astub in the same directory as BaseTypeChecker Stub files listed in @Stubfiles annotation on the checker; must be in same directory as the checker Stub files provide via stubs system property Stub files provide via stubs environment variable Stub files provide via stubs compiler option |
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 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 final boolean ignoreUninferredTypeArguments
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()
-Ainfer
is passed as an option. It checks if another
option that should not occur simultaneously with the whole-program inference is also passed
as argument, and aborts the process if that is the case. For example, the whole-program
inference process was not designed to work with unchecked code defaults. (Subclasses may
override this method to add more options.)protected void postInit()
public WholeProgramInference getWholeProgramInference()
protected void initializeReflectionResolution()
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
, if a polymorphic type qualifier exists, 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()
public AnnotatedTypeFormatter getAnnotatedTypeFormatter()
protected AnnotationFormatter createAnnotationFormatter()
public AnnotationFormatter getAnnotationFormatter()
public final Set<Class<? extends Annotation>> getSupportedTypeQualifiers()
Subclasses cannot override this method; they should override createSupportedTypeQualifiers
instead.
createSupportedTypeQualifiers()
protected int getCacheSize()
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 addDefaultAnnotations(AnnotatedTypeMirror type)
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()
.)type
- annotated type to which default annotations are addedprotected 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 methodprotected void addAnnotationFromFieldInvariant(AnnotatedTypeMirror type, AnnotatedTypeMirror accessedVia, VariableElement field)
field
to type
.type
- annotated type to which the annotation is addedaccessedVia
- the annotated type of the receiver of the accessing tree. (Only used to
get the type element of the underling type.)field
- element representing the fieldpublic FieldInvariants getFieldInvariants(TypeElement element)
Subclass may implement their own field invariant annotations if FieldInvariant
is
not expressive enough. They must override this method to properly create AnnotationMirror and
also override getFieldInvariantDeclarationAnnotations()
to return their field
invariants.
element
- class for which to get invariantselement
public AnnotationTree getFieldInvariantAnnotationTree(List<? extends AnnotationTree> annoTrees)
getFieldInvariantDeclarationAnnotations()
. If one isn't found, null is
returned.annoTrees
- trees to lookprotected Set<Class<? extends Annotation>> getFieldInvariantDeclarationAnnotations()
public 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 void adaptGetClassReturnTypeToReceiver(AnnotatedTypeMirror.AnnotatedExecutableType getClassType, AnnotatedTypeMirror receiverType)
getClass()
. Though
the method has a return type of Class<?>
, the compiler special cases this return-type
and changes the bound of the type argument to the erasure of the receiver type. For example:
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 thrown. It is modified by side effect.receiverType
- 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 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.
(Subclass beside GenericAnnotatedTypeFactory
should not override this method.)
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 narrownarrowedTypeMirror
- 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<?> aliasClass, AnnotationMirror type)
aliasClass
as an alias for the canonical annotation type
that will be used by the Checker Framework in the alias's place.
By specifying the alias/canonical relationship using this method, the elements of the
alias are not preserved when the canonical annotation to use is constructed from the alias.
If you want the elements to be copied over as well, please refer to addAliasedAnnotation(Class, AnnotationMirror, boolean, String...)
.
aliasClass
- the class of the aliased annotationtype
- the canonical annotationprotected void addAliasedAnnotation(String aliasName, AnnotationMirror type)
aliasName
, as an alias
for the canonical annotation type
that will be used by the Checker Framework in the
alias's place.
This overload provides a workaround when the alias class cannot be referenced directly. In
general, it is nicer and less error-prone to use the addAliasedAnnotation(Class,
AnnotationMirror)
version instead.
aliasName
- the fully-qualified name of the aliased annotationtype
- the canonical annotationprotected void addAliasedAnnotation(Class<?> aliasClass, AnnotationMirror type, boolean copyElements, String... ignorableElements)
aliasClass
as an alias for the canonical annotation type
that will be used by the Checker Framework in the alias's place.
You may specify the copyElements flag to indicate whether you want the elements of the alias to be copied over when the canonical annotation is constructed. Be careful that the framework will try to copy the elements by name matching, so make sure that names and types of the elements to be copied over are exactly the same as the ones in the canonical annotation. Otherwise, an 'Couldn't find element in annotation' error is raised.
To facilitate the cases where some of the elements is ignored on purpose when constructing
the canonical annotation, this method also provides a varargs ignorableElements
for
you to explicitly specify the ignoring rules. For example, @IndexFor
is an alias of @NonNegative
, but the element "value" of
@IndexFor
should be ignored when constructing @NonNegative
. In the cases
where all elements are ignored, we can simply use addAliasedAnnotation(Class,
AnnotationMirror)
instead.
aliasClass
- the class of the aliased annotationtype
- the canonical annotationcopyElements
- a flag that indicates whether you want to copy the elements over when
getting the alias from the canonical annotationignorableElements
- a list of elements that can be safely dropped when the elements are
being copied overprotected void addAliasedAnnotation(String aliasName, AnnotationMirror type, boolean copyElements, String... ignorableElements)
aliasName
, as an alias
for the canonical annotation type
that will be used by the Checker Framework in the
alias's place.
This overload provides a workaround when the alias class cannot be referenced directly. In
general, it is nicer and less error-prone to use the addAliasedAnnotation(Class,
AnnotationMirror)
version instead.
aliasName
- the fully-qualified name of the aliased classtype
- the canonical annotationcopyElements
- a flag that indicates whether we want to copy the elements over when
getting the alias from the canonical annotationignorableElements
- a list of elements that can be safely dropped when the elements are
being copied overpublic @Nullable AnnotationMirror aliasedAnnotation(AnnotationMirror a)
A canonical annotation is the internal annotation that will be used by the Checker Framework in the aliased annotation's place.
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)
TODO: would be nice to move this to InternalUtils/TreeUtils.
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 annotationspublic List<Pair<AnnotationMirror,AnnotationMirror>> getDeclAnnotationWithMetaAnnotation(Element element, Class<? extends Annotation> metaAnnotation)
metaAnnotation
.element
- the element for which to determine annotationsmetaAnnotation
- 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 annotationsmetaAnnotation
- 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)
AnnotatedTypeMirror.AnnotatedWildcardType.isUninferredTypeArgument()
returns true.
This method should only be used by type argument inference. org.checkerframework.framework.util.AnnotatedTypes.inferTypeArguments(ProcessingEnvironment, AnnotatedTypeFactory, ExpressionTree, ExecutableElement)
typeVar
- TypeVariable which could not be inferredpublic 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 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()