Class DependentTypesHelper
- Direct Known Subclasses:
OffsetDependentTypesHelper
- Converts the expression strings in an
AnnotationMirroram, 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.)
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprotected classReplaces a dependent type annotation with a parser error with the top qualifier in the hierarchy.protected classThe underlying type of the second parameter is the result of applying type variable substitution to the visited type (the first parameter). -
Field Summary
FieldsModifier and TypeFieldDescriptionprotected final DependentTypesHelper.ErrorAnnoReplacerThis scans the annotated type and replaces any dependent type annotation that has a parse error with the top annotation in the hierarchy.protected final AnnotatedTypeFactoryAnnotatedTypeFactoryprotected final TypeMirrorThe type mirror for java.lang.Object.protected final DependentTypesHelper.ViewpointAdaptedCopierCopies annotations that might have been viewpoint adapted from the visited type (the first formal parameter ofViewpointAdaptedCopier#visit) to the second formal parameter. -
Constructor Summary
ConstructorsConstructorDescriptionDependentTypesHelper(AnnotatedTypeFactory factory) Creates aDependentTypesHelper. -
Method Summary
Modifier and TypeMethodDescriptionvoidatConstructorInvocation(AnnotatedTypeMirror.AnnotatedExecutableType constructorType, NewClassTree newClassTree) Viewpoint-adapts the dependent type annotations in the constructorType to the newClassTree.voidatExpression(AnnotatedTypeMirror annotatedType, ExpressionTree expressionTree) Standardize the Java expressions in annotations in written in theexpressionTree.voidatFieldAccess(AnnotatedTypeMirror type, MemberSelectTree fieldAccess) Viewpoint-adapts the Java expressions in annotations written on a field declaration to the use atfieldAccess.voidatLocalVariable(AnnotatedTypeMirror type, Element elt) Standardize the Java expressions in annotations in a type.voidatMethodBody(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.voidatMethodInvocation(AnnotatedTypeMirror.AnnotatedExecutableType methodType, MethodInvocationTree methodInvocationTree) Viewpoint-adapts the dependent type annotations in the methodType to the methodInvocationTree.voidatParameterizedTypeUse(List<AnnotatedTypeParameterBounds> bounds, TypeElement typeUse) Viewpoint-adapts the dependent type annotations on the bounds of the type parameters of the declaration oftypeUsetotypeUse.voidatTypeDecl(AnnotatedTypeMirror type, TypeElement typeElt) Standardizes the Java expressions in annotations to a type declaration.voidatVariableDeclaration(AnnotatedTypeMirror type, Tree declarationTree, VariableElement variableElt) Standardize the Java expressions in annotations in a variable declaration.protected AnnotationMirrorbuildAnnotation(AnnotationMirror originalAnno, Map<ExecutableElement, List<JavaExpression>> elementMap) Create a new annotation of the same type asoriginalAnnousing the providedelementMap.voidcheckAnnotationForErrorExpressions(AnnotationMirror annotation, Tree errorTree) Reports a flowexpr.parse.error error for each Java expression in the given annotation that is an expression error string.voidReports an expression.unparsable error for each Java expression in the given class declaration AnnotatedTypeMirror that is an expression error string.voidcheckMethodForErrorExpressions(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.voidcheckTypeForErrorExpressions(AnnotatedTypeMirror atm, Tree errorTree) Reports an expression.unparsable error for each Java expression in the given type that is an expression error string.protected voidconvertAnnotatedTypeMirror(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.PassThroughExpressioncreateError(String expression, String error) Creates aJavaExpressionrepresenting the error caused when parsingexpressionprotected org.checkerframework.framework.util.dependenttypes.DependentTypesHelper.PassThroughExpressionCreates aJavaExpressionrepresenting the exception thrown when parsingexpression.voiddelocalize(AnnotatedTypeMirror atm, MethodTree methodDeclTree) Viewpoint-adapt all dependent type annotations to the method declaration,methodDeclTree.voiddelocalizeAtCallsite(AnnotatedTypeMirror atm, Tree invocationTree, List<Node> arguments, @Nullable Node receiver, ExecutableElement methodElt) Delocalizes dependent type annotations inatmso that they can be placed on the declaration of the given method or constructor being invoked.booleanReturns true if any qualifier in the type system is a dependent type annotation.protected booleanReturns true ifatmhas any dependent type annotations.protected voidreportErrors(Tree errorTree, List<DependentTypesError> errors) Report the given errors as "expression.unparsable".protected booleanshouldPassThroughExpression(String expression) Whether or notexpressionshould be passed to the new annotation unchanged.protected @Nullable JavaExpressiontransform(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 -
errorAnnoReplacer
This scans the annotated type and replaces any dependent type annotation that has a parse error with the top annotation in the hierarchy. -
viewpointAdaptedCopier
Copies annotations that might have been viewpoint adapted from the visited type (the first formal parameter ofViewpointAdaptedCopier#visit) to the second formal parameter. -
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 oftypeUsetotypeUse.- 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.methodTypehas 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.constructorTypehas 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.expressionTreemust be an expressions which can contain explicitly written annotations, namely aNewClassTree,NewArrayTree, orTypeCastTree. For example, this method standardizes theKeyForannotation 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
atmreferences 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 inatmso 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 aJavaExpressiontype- 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. Ifannois not a dependent type annotation,nullis returned.If
stringToJavaExprreturnsnull, 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 toJavaExpressionsanno- annotation mirror- Returns:
- an annotation created by applying
stringToJavaExprto 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.javaExprmay be aDependentTypesHelper.PassThroughExpression.If
nullis 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
nullif no transformation exists
-
shouldPassThroughExpression
Whether or notexpressionshould be passed to the new annotation unchanged. If this method returns true, theexpressionis not parsed.The default implementation returns true if the
expressionis 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
expressionshould 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 asoriginalAnnousing the providedelementMap.- Parameters:
originalAnno- the annotation passed toconvertAnnotationMirror(StringToJavaExpression, AnnotationMirror)(this method is a helper method forconvertAnnotationMirror(StringToJavaExpression, AnnotationMirror))elementMap- a mapping from element oforiginalAnnotoJavaExpressions- Returns:
- an annotation created from
elementMap
-
createError
protected org.checkerframework.framework.util.dependenttypes.DependentTypesHelper.PassThroughExpression createError(String expression, JavaExpressionParseUtil.JavaExpressionParseException e) Creates aJavaExpressionrepresenting the exception thrown when parsingexpression.- Parameters:
expression- an expression that causedewhen 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 aJavaExpressionrepresenting the error caused when parsingexpression- Parameters:
expression- an expression that causederrorwhen 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
-
hasDependentType
Returns true ifatmhas any dependent type annotations. If an annotated type does not have a dependent type annotation, then no standardization or viewpoint adaption is performed. (This check avoids calling time-intensive methods unless required.)- Parameters:
atm- a type- Returns:
- true if
atmhas any dependent type annotations
-