Class DependentTypesHelper
- Direct Known Subclasses:
OffsetDependentTypesHelper
- Converts the expression strings in an
AnnotationMirror
am
, by creating a new annotation whose Java expression elements are the result of the conversion. SeeconvertAnnotationMirror(StringToJavaExpression, AnnotationMirror)
, though clients do not call it (they call other methods in this class, which eventually call it). 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.- Standardization: the expressions in the annotations are converted such that two
expression strings that are equivalent are made to be equal. For example, an instance
field f may appear in an expression string as "f" or "this.f"; this class
standardizes both strings to "this.f". All dependent type annotations must be
standardized so that the implementation of
QualifierHierarchy.isSubtypeShallow(AnnotationMirror, TypeMirror, AnnotationMirror, TypeMirror)
can assume that two expressions are equivalent if their string representations areequals()
. - Viewpoint-adaption: converts an expression to some use site. For example, in method bodies, formal parameter references such as "#2" are converted to the name of the formal parameter. Another example, is at method call site, "this" is converted to the receiver of the method invocation.
- Delocalization: removes all expressions with references to local variables that are not parameters and changes parameters to the "#1" syntax.
- Standardization: the expressions in the annotations are converted such that two
expression strings that are equivalent are made to be equal. For example, an instance
field f may appear in an expression string as "f" or "this.f"; this class
standardizes both strings to "this.f". All dependent type annotations must be
standardized so that the implementation of
- If any of the conversions above results in an invalid expression, this class changes
invalid expression strings to an error string that includes the reason why the expression
is invalid. For example,
@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. - Checks annotated types for error strings that have been added by this class and issues an error if any are found.
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.)
-
Field Summary
Modifier and TypeFieldDescriptionprotected final AnnotatedTypeFactory
AnnotatedTypeFactoryprotected final TypeMirror
The type mirror for java.lang.Object. -
Constructor Summary
ConstructorDescriptionDependentTypesHelper
(AnnotatedTypeFactory factory) Creates aDependentTypesHelper
. -
Method Summary
Modifier and TypeMethodDescriptionvoid
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 theexpressionTree
.void
atFieldAccess
(AnnotatedTypeMirror type, MemberSelectTree fieldAccess) Viewpoint-adapts the Java expressions in annotations written on a field declaration to the use atfieldAccess
.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 oftypeUse
totypeUse
.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 asoriginalAnno
using the providedelementMap
.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
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) CallsconvertAnnotationMirror(StringToJavaExpression, AnnotationMirror)
on each annotation mirror on type withstringToJavaExpr
.convertAnnotationMirror
(StringToJavaExpression stringToJavaExpr, AnnotationMirror anno) Given an annotationanno
, this method builds a new annotation with the Java expressions transformed according tostringToJavaExpr
.Creates a TreeAnnotator that viewpoint-adapts dependent type annotations.protected org.checkerframework.framework.util.dependenttypes.DependentTypesHelper.PassThroughExpression
createError
(String expression, String error) Creates aJavaExpression
representing the error caused when parsingexpression
protected org.checkerframework.framework.util.dependenttypes.DependentTypesHelper.PassThroughExpression
Creates aJavaExpression
representing the exception thrown when parsingexpression
.void
delocalize
(AnnotatedTypeMirror atm, MethodTree methodDeclTree) Viewpoint-adapt all dependent type annotations to the method declaration,methodDeclTree
.void
delocalizeAtCallsite
(AnnotatedTypeMirror atm, Tree invocationTree, List<Node> arguments, @Nullable Node receiver, ExecutableElement methodElt) Delocalizes dependent type annotations inatm
so that they can be placed on the declaration of the given method or constructor being invoked.boolean
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 notexpression
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.
-
Field Details
-
factory
AnnotatedTypeFactory -
objectTM
The type mirror for java.lang.Object.
-
-
Constructor Details
-
DependentTypesHelper
Creates aDependentTypesHelper
.- Parameters:
factory
- annotated type factory
-
-
Method Details
-
hasDependentAnnotations
public boolean hasDependentAnnotations()Returns true if any qualifier in the type system is a dependent type annotation.- Returns:
- true if any qualifier in the type system is a dependent type annotation
-
createDependentTypesTreeAnnotator
Creates a TreeAnnotator that viewpoint-adapts dependent type annotations.- Returns:
- a new TreeAnnotator that viewpoint-adapts dependent type annotations
-
atParameterizedTypeUse
Viewpoint-adapts the dependent type annotations on the bounds of the type parameters of the declaration oftypeUse
totypeUse
.- Parameters:
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 boundsbounds
-
atMethodInvocation
public void atMethodInvocation(AnnotatedTypeMirror.AnnotatedExecutableType methodType, MethodInvocationTree methodInvocationTree) Viewpoint-adapts the dependent type annotations in the methodType to the methodInvocationTree.methodType
has been viewpoint-adapted to the call site, except for any dependent type annotations. This method viewpoint-adapts the dependent type annotations.- Parameters:
methodType
- type of the method invocation; is side-effected by this methodmethodInvocationTree
- use of the method
-
atConstructorInvocation
public void atConstructorInvocation(AnnotatedTypeMirror.AnnotatedExecutableType constructorType, NewClassTree newClassTree) Viewpoint-adapts the dependent type annotations in the constructorType to the newClassTree.constructorType
has been viewpoint-adapted to the call site, except for any dependent type annotations. This method viewpoint-adapts the dependent type annotations.- Parameters:
constructorType
- type of the constructor invocation; is side-effected by this methodnewClassTree
- invocation of the constructor
-
atFieldAccess
Viewpoint-adapts the Java expressions in annotations written on a field declaration to the use atfieldAccess
.- Parameters:
type
- its type; is side-effected by this methodfieldAccess
- a field access
-
atMethodBody
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. This means the parameter syntax, e.g. "#2", is converted to the names of the parameter.- Parameters:
atm
- a type at the method signature; is side-effected by this methodmethodDeclTree
- a method declaration
-
atTypeDecl
Standardizes the Java expressions in annotations to a type declaration.- Parameters:
type
- the type of the type declaration; is side-effected by this methodtypeElt
- the element of the type declaration
-
atVariableDeclaration
public void atVariableDeclaration(AnnotatedTypeMirror type, Tree declarationTree, VariableElement variableElt) Standardize the Java expressions in annotations in a variable declaration. Converts the parameter syntax, e.g "#1", to the parameter name.- Parameters:
type
- the type of the variable declaration; is side-effected by this methoddeclarationTree
- the variable declarationvariableElt
- the element of the variable declaration
-
atExpression
Standardize the Java expressions in annotations in written in theexpressionTree
. Also, converts the parameter syntax, e.g. "#1", to the parameter name.expressionTree
must be an expressions which can contain explicitly written annotations, namely aNewClassTree
,NewArrayTree
, orTypeCastTree
. For example, this method standardizes theKeyFor
annotation in(@KeyFor("map") String) key
.- Parameters:
annotatedType
- its type; is side-effected by this methodexpressionTree
- aNewClassTree
,NewArrayTree
, orTypeCastTree
-
atLocalVariable
Standardize the Java expressions in annotations in a type. Converts the parameter syntax, e.g. "#2", to the parameter name.- Parameters:
type
- the type to standardize; is side-effected by this methodelt
- the element whose type istype
-
delocalize
Viewpoint-adapt all dependent type annotations to the method declaration,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 overridebuildAnnotation(AnnotationMirror, Map)
to do something besides creating an annotation with a empty list.- Parameters:
atm
- type to viewpoint-adapt; is side-effected by this methodmethodDeclTree
- the method declaration to which the annotations are viewpoint-adapted
-
delocalizeAtCallsite
public void delocalizeAtCallsite(AnnotatedTypeMirror atm, Tree invocationTree, List<Node> arguments, @Nullable Node receiver, ExecutableElement methodElt) Delocalizes dependent type annotations inatm
so that they can be placed on the declaration of the given method or constructor being invoked. Used by whole program inference to infer dependent types for method/constructor parameters based on the actual arguments used at call sites.- Parameters:
atm
- the annotated type mirror to delocalizeinvocationTree
- the method or constructor invocationarguments
- the actual arguments to the method or constructorreceiver
- the actual receiver, if there was one; null if notmethodElt
- the declaration of the method or constructor being invoked
-
convertAnnotatedTypeMirror
protected void convertAnnotatedTypeMirror(StringToJavaExpression stringToJavaExpr, AnnotatedTypeMirror type) CallsconvertAnnotationMirror(StringToJavaExpression, AnnotationMirror)
on each annotation mirror on type withstringToJavaExpr
. And replaces the annotation with the one created byconvertAnnotationMirror
, if it's not null. If it is null, the original annotation is used. SeeconvertAnnotationMirror(StringToJavaExpression, AnnotationMirror)
for more details.- Parameters:
stringToJavaExpr
- function to convert a string to aJavaExpression
type
- the type that is side-effected by this method
-
convertAnnotationMirror
public @Nullable AnnotationMirror convertAnnotationMirror(StringToJavaExpression stringToJavaExpr, AnnotationMirror anno) Given an annotationanno
, this method builds a new annotation with the Java expressions transformed according tostringToJavaExpr
. Ifanno
is not a dependent type annotation,null
is returned.If
stringToJavaExpr
returnsnull
, 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 bystringToJavaExpr
.buildAnnotation(AnnotationMirror, Map)
: to change the annotation returned by this method.
- Parameters:
stringToJavaExpr
- function that converts strings toJavaExpression
sanno
- annotation mirror- Returns:
- an annotation created by applying
stringToJavaExpr
to all expression strings inanno
, or null if there would be no effect
-
transform
This method is for subclasses to override to change JavaExpressions in some way before they are inserted into new annotations. This method is called after parsing and viewpoint-adaptation have occurred.javaExpr
may be aDependentTypesHelper.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.
- Parameters:
javaExpr
- a JavaExpression- Returns:
- a transformed JavaExpression or
null
if no transformation exists
-
shouldPassThroughExpression
Whether or notexpression
should be passed to the new annotation unchanged. If this method returns true, theexpression
is not parsed.The default implementation returns true if the
expression
is an expression error according toDependentTypesError.isExpressionError(String)
. Subclasses may override this method to add additional logic.- Parameters:
expression
- an expression string in a dependent types annotation- Returns:
- whether or not
expression
should be passed through unchanged to the new annotation
-
buildAnnotation
protected AnnotationMirror buildAnnotation(AnnotationMirror originalAnno, Map<ExecutableElement, List<JavaExpression>> elementMap) Create a new annotation of the same type asoriginalAnno
using the providedelementMap
.- Parameters:
originalAnno
- the annotation passed toconvertAnnotationMirror(StringToJavaExpression, AnnotationMirror)
(this method is a helper method forconvertAnnotationMirror(StringToJavaExpression, AnnotationMirror)
)elementMap
- a mapping from element oforiginalAnno
toJavaExpression
s- Returns:
- an annotation created from
elementMap
-
createError
protected org.checkerframework.framework.util.dependenttypes.DependentTypesHelper.PassThroughExpression createError(String expression, JavaExpressionParseUtil.JavaExpressionParseException e) Creates aJavaExpression
representing the exception thrown when parsingexpression
.- Parameters:
expression
- an expression that causede
when parsede
- the exception thrown when parsingexpression
- Returns:
- a Java expression
-
createError
protected org.checkerframework.framework.util.dependenttypes.DependentTypesHelper.PassThroughExpression createError(String expression, String error) Creates aJavaExpression
representing the error caused when parsingexpression
- Parameters:
expression
- an expression that causederror
when parsederror
- the error message caused byexpression
- Returns:
- a Java expression
-
checkTypeForErrorExpressions
Reports an expression.unparsable error for each Java expression in the given type that is an expression error string.- Parameters:
atm
- annotated type to check for expression errorserrorTree
- the tree at which to report any found errors
-
reportErrors
Report the given errors as "expression.unparsable".- Parameters:
errorTree
- where to report the errorserrors
- the errors to report
-
checkAnnotationForErrorExpressions
Reports a flowexpr.parse.error error for each Java expression in the given annotation that is an expression error string.- Parameters:
annotation
- annotation to checkerrorTree
- location at which to issue errors
-
checkClassForErrorExpressions
public 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. Note that this reports errors in the class declaration itself, not the body or extends/implements clauses.- Parameters:
classTree
- class to checktype
- annotated type of the class
-
checkMethodForErrorExpressions
public 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.- Parameters:
methodDeclTree
- method to checktype
- annotated type of the method
-