public class DependentTypesHelper extends Object
AnnotationMirror
am
, by creating a
new annotation whose Java expression elements are the result of the conversion. See convertAnnotationMirror(StringToJavaExpression, AnnotationMirror)
. Subclasses can
specialize this process by overriding methods in this class. Methods in this class always
standardize Java expressions and may additionally viewpoint-adapt or delocalize
expressions. Below is an explanation of each kind of conversion.
QualifierHierarchy.isSubtype(AnnotationMirror,
AnnotationMirror)
can assume that two expressions are equivalent if their string
representations are equals()
.
@KeyFor("m")
would be changed to @KeyFor("[error
for expression: m error: m: identifier not found]")
if m is not a valid identifier. This
allows subtyping checks to assume that if two strings are equal and not errors, they
reference the same valid Java expression.
Steps 2 and 3 are separated so that an error is issued only once per invalid expression string rather than every time the expression string is parsed. (The expression string is parsed multiple times because annotated types are created multiple times.)
Modifier and Type | Field and Description |
---|---|
protected AnnotatedTypeFactory |
factory
AnnotatedTypeFactory
|
protected TypeMirror |
objectTM
The type mirror for java.lang.Object.
|
Constructor and Description |
---|
DependentTypesHelper(AnnotatedTypeFactory factory)
Creates a
DependentTypesHelper . |
Modifier and Type | Method and Description |
---|---|
void |
atConstructorInvocation(AnnotatedTypeMirror.AnnotatedExecutableType constructorType,
NewClassTree newClassTree)
Viewpoint-adapts the dependent type annotations in the constructorType to the newClassTree.
|
void |
atExpression(AnnotatedTypeMirror annotatedType,
ExpressionTree expressionTree)
Standardize the Java expressions in annotations in written in the
expressionTree . |
void |
atFieldAccess(AnnotatedTypeMirror type,
MemberSelectTree fieldAccess)
Viewpoint-adapts the Java expressions in annotations written on a field declaration to the use
at
fieldAccess . |
void |
atLocalVariable(AnnotatedTypeMirror type,
Element elt)
Standardize the Java expressions in annotations in a type.
|
void |
atMethodBody(AnnotatedTypeMirror atm,
MethodTree methodDeclTree)
Viewpoint-adapts the Java expressions in annotations written on the signature of the method
declaration (for example, a return type) to the body of the method.
|
void |
atMethodInvocation(AnnotatedTypeMirror.AnnotatedExecutableType methodType,
MethodInvocationTree methodInvocationTree)
Viewpoint-adapts the dependent type annotations in the methodType to the methodInvocationTree.
|
void |
atParameterizedTypeUse(List<AnnotatedTypeParameterBounds> bounds,
TypeElement typeUse)
Viewpoint-adapts the dependent type annotations on the bounds of the type parameters of the
declaration of
typeUse to typeUse . |
void |
atTypeDecl(AnnotatedTypeMirror type,
TypeElement typeElt)
Standardizes the Java expressions in annotations to a type declaration.
|
void |
atVariableDeclaration(AnnotatedTypeMirror type,
Tree declarationTree,
VariableElement variableElt)
Standardize the Java expressions in annotations in a variable declaration.
|
protected AnnotationMirror |
buildAnnotation(AnnotationMirror originalAnno,
Map<ExecutableElement,List<JavaExpression>> elementMap)
Create a new annotation of the same type as
originalAnno using the provided elementMap . |
void |
checkAnnotationForErrorExpressions(AnnotationMirror annotation,
Tree errorTree)
Reports a flowexpr.parse.error error for each Java expression in the given annotation that is
an expression error string.
|
void |
checkClassForErrorExpressions(ClassTree classTree,
AnnotatedTypeMirror.AnnotatedDeclaredType type)
Reports an expression.unparsable error for each Java expression in the given class declaration
AnnotatedTypeMirror that is an expression error string.
|
void |
checkMethodForErrorExpressions(MethodTree methodDeclTree,
AnnotatedTypeMirror.AnnotatedExecutableType type)
Reports an expression.unparsable error for each Java expression in the method declaration
AnnotatedTypeMirror that is an expression error string.
|
void |
checkTypeForErrorExpressions(AnnotatedTypeMirror atm,
Tree errorTree)
Reports an expression.unparsable error for each Java expression in the given type that is an
expression error string.
|
protected void |
convertAnnotatedTypeMirror(StringToJavaExpression stringToJavaExpr,
AnnotatedTypeMirror type)
Calls
convertAnnotationMirror(StringToJavaExpression, AnnotationMirror) on each
annotation mirror on type with stringToJavaExpr . |
@Nullable AnnotationMirror |
convertAnnotationMirror(StringToJavaExpression stringToJavaExpr,
AnnotationMirror anno)
Given an annotation
anno , this method builds a new annotation with the Java expressions
transformed according to stringToJavaExpr . |
TreeAnnotator |
createDependentTypesTreeAnnotator()
Creates a TreeAnnotator that viewpoint-adapts dependent type annotations.
|
protected org.checkerframework.framework.util.dependenttypes.DependentTypesHelper.PassThroughExpression |
createError(String expression,
JavaExpressionParseUtil.JavaExpressionParseException e)
Creates a
JavaExpression representing the exception thrown when parsing expression . |
protected org.checkerframework.framework.util.dependenttypes.DependentTypesHelper.PassThroughExpression |
createError(String expression,
String error)
Creates a
JavaExpression representing the error caused when parsing expression |
void |
delocalize(AnnotatedTypeMirror atm,
MethodTree methodDeclTree)
Viewpoint-adapt all dependent type annotations to the method declaration,
methodDeclTree . |
boolean |
hasDependentAnnotations()
Returns true if any qualifier in the type system is a dependent type annotation.
|
protected void |
reportErrors(Tree errorTree,
List<DependentTypesError> errors)
Report the given errors as "expression.unparsable".
|
protected boolean |
shouldPassThroughExpression(String expression)
Whether or not
expression should be passed to the new annotation unchanged. |
protected @Nullable JavaExpression |
transform(JavaExpression javaExpr)
This method is for subclasses to override to change JavaExpressions in some way before they are
inserted into new annotations.
|
protected final AnnotatedTypeFactory factory
protected final TypeMirror objectTM
public DependentTypesHelper(AnnotatedTypeFactory factory)
DependentTypesHelper
.factory
- annotated type factorypublic boolean hasDependentAnnotations()
public TreeAnnotator createDependentTypesTreeAnnotator()
public void atParameterizedTypeUse(List<AnnotatedTypeParameterBounds> bounds, TypeElement typeUse)
typeUse
to typeUse
.bounds
- annotated types of the bounds of the type parameters; its elements are
side-effected by this method (but the list itself is not side-effected)typeUse
- a use of a type with type parameter bounds bounds
public void atMethodInvocation(AnnotatedTypeMirror.AnnotatedExecutableType methodType, MethodInvocationTree methodInvocationTree)
methodType
has been viewpoint-adapted to the call site, except for any dependent
type annotations. This method viewpoint-adapts the dependent type annotations.
methodType
- type of the method invocation; is side-effected by this methodmethodInvocationTree
- use of the methodpublic void atConstructorInvocation(AnnotatedTypeMirror.AnnotatedExecutableType constructorType, NewClassTree newClassTree)
constructorType
has been viewpoint-adapted to the call site, except for any
dependent type annotations. This method viewpoint-adapts the dependent type annotations.
constructorType
- type of the constructor invocation; is side-effected by this methodnewClassTree
- invocation of the constructorpublic void atFieldAccess(AnnotatedTypeMirror type, MemberSelectTree fieldAccess)
fieldAccess
.type
- its type; is side-effected by this methodfieldAccess
- a field accesspublic void atMethodBody(AnnotatedTypeMirror atm, MethodTree methodDeclTree)
atm
- a type at the method signature; is side-effected by this methodmethodDeclTree
- a method declarationpublic void atTypeDecl(AnnotatedTypeMirror type, TypeElement typeElt)
type
- the type of the type declaration; is side-effected by this methodtypeElt
- the element of the type declarationpublic void atVariableDeclaration(AnnotatedTypeMirror type, Tree declarationTree, VariableElement variableElt)
type
- the type of the variable declaration; is side-effected by this methoddeclarationTree
- the variable declarationvariableElt
- the element of the variable declarationpublic void atExpression(AnnotatedTypeMirror annotatedType, ExpressionTree expressionTree)
expressionTree
. Also,
converts the parameter syntax, e.g. "#1", to the parameter name.
expressionTree
must be an expressions which can contain explicitly written
annotations, namely a NewClassTree
, NewArrayTree
, or TypeCastTree
. For example, this method standardizes the KeyFor
annotation in (@KeyFor("map") String) key
.
annotatedType
- its type; is side-effected by this methodexpressionTree
- a NewClassTree
, NewArrayTree
, or
TypeCastTree
public void atLocalVariable(AnnotatedTypeMirror type, Element elt)
type
- the type to standardize; is side-effected by this methodelt
- the element whose type is type
public void delocalize(AnnotatedTypeMirror atm, MethodTree methodDeclTree)
methodDeclTree
. This method changes occurrences of formal parameter names to the "#2" syntax,
and it removes expressions that contain other local variables.
If a Java expression in atm
references local variables (other than formal
parameters), the expression is removed from the annotation. This could result in dependent type
annotations with empty lists of expressions. If this is a problem, a subclass can override
buildAnnotation(AnnotationMirror, Map)
to do something besides creating an annotation
with a empty list.
atm
- type to viewpoint-adapt; is side-effected by this methodmethodDeclTree
- the method declaration to which the annotations are viewpoint-adaptedprotected void convertAnnotatedTypeMirror(StringToJavaExpression stringToJavaExpr, AnnotatedTypeMirror type)
convertAnnotationMirror(StringToJavaExpression, AnnotationMirror)
on each
annotation mirror on type with stringToJavaExpr
. And replaces the annotation with the
one created by convertAnnotationMirror
, if it's not null. If it is null, the original
annotation is used. See convertAnnotationMirror(StringToJavaExpression,
AnnotationMirror)
for more details.stringToJavaExpr
- function to convert a string to a JavaExpression
type
- the type that is side-effected by this methodpublic @Nullable AnnotationMirror convertAnnotationMirror(StringToJavaExpression stringToJavaExpr, AnnotationMirror anno)
anno
, this method builds a new annotation with the Java expressions
transformed according to stringToJavaExpr
. If anno
is not a dependent type
annotation, null
is returned.
If stringToJavaExpr
returns null
, then that expression is removed from the
returned annotation.
Instead of overriding this method, subclasses can override the following methods to change the behavior of this class:
shouldPassThroughExpression(String)
: to control which expressions are skipped.
If this method returns true, then the expression string is not parsed and is included in
the new annotation unchanged.
transform(JavaExpression)
: make changes to the JavaExpression produced by stringToJavaExpr
.
buildAnnotation(AnnotationMirror, Map)
: to change the annotation returned by
this method.
stringToJavaExpr
- function that converts strings to JavaExpression
sanno
- annotation mirrorstringToJavaExpr
to all expression strings in
anno
, or null if there would be no effectprotected @Nullable JavaExpression transform(JavaExpression javaExpr)
javaExpr
may be a PassThroughExpression
.
If null
is returned then the expression is not added to the new annotation.
The default implementation returns the argument, but subclasses may override it.
javaExpr
- a JavaExpressionnull
if no transformation existsprotected boolean shouldPassThroughExpression(String expression)
expression
should be passed to the new annotation unchanged. If this
method returns true, the expression
is not parsed.
The default implementation returns true if the expression
is an expression error
according to DependentTypesError.isExpressionError(String)
. Subclasses may override
this method to add additional logic.
expression
- an expression string in a dependent types annotationexpression
should be passed through unchanged to the new
annotationprotected AnnotationMirror buildAnnotation(AnnotationMirror originalAnno, Map<ExecutableElement,List<JavaExpression>> elementMap)
originalAnno
using the provided elementMap
.originalAnno
- the annotation passed to convertAnnotationMirror(StringToJavaExpression, AnnotationMirror)
(this method is a
helper method for convertAnnotationMirror(StringToJavaExpression,
AnnotationMirror)
)elementMap
- a mapping from element of originalAnno
to JavaExpression
selementMap
protected org.checkerframework.framework.util.dependenttypes.DependentTypesHelper.PassThroughExpression createError(String expression, JavaExpressionParseUtil.JavaExpressionParseException e)
JavaExpression
representing the exception thrown when parsing expression
.expression
- an expression that caused e
when parsede
- the exception thrown when parsing expression
protected org.checkerframework.framework.util.dependenttypes.DependentTypesHelper.PassThroughExpression createError(String expression, String error)
JavaExpression
representing the error caused when parsing expression
expression
- an expression that caused error
when parsederror
- the error message caused by expression
public void checkTypeForErrorExpressions(AnnotatedTypeMirror atm, Tree errorTree)
atm
- annotated type to check for expression errorserrorTree
- the tree at which to report any found errorsprotected void reportErrors(Tree errorTree, List<DependentTypesError> errors)
errorTree
- where to report the errorserrors
- the errors to reportpublic void checkAnnotationForErrorExpressions(AnnotationMirror annotation, Tree errorTree)
annotation
- annotation to checkerrorTree
- location at which to issue errorspublic void checkClassForErrorExpressions(ClassTree classTree, AnnotatedTypeMirror.AnnotatedDeclaredType type)
classTree
- class to checktype
- annotated type of the classpublic void checkMethodForErrorExpressions(MethodTree methodDeclTree, AnnotatedTypeMirror.AnnotatedExecutableType type)
methodDeclTree
- method to checktype
- annotated type of the method