Class TypeArgInferenceUtil
java.lang.Object
org.checkerframework.framework.util.typeinference.TypeArgInferenceUtil
Miscellaneous utilities to help in type argument inference.
-
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionstatic @Nullable AnnotatedTypeMirror
assignedTo
(AnnotatedTypeFactory atypeFactory, TreePath path) Returns the annotated type that the leaf of path is assigned to, if it is within an assignment context.static AnnotatedTypeMirror
assignedToVariable
(AnnotatedTypeFactory atypeFactory, VariableTree assignmentContext) If the variable's type is a type variable, return getAnnotatedTypeLhsNoTypeVarDefault(tree).static void
Throws an exception if the type is an uninferred type argument.static boolean
containsTypeParameter
(AnnotatedTypeMirror type, Collection<TypeVariable> typeVariables) Returns true iftype
contains a use of a type variable intypeVariables
.protected static Map<TypeVariable,
AnnotatedTypeMirror> correctResults
(Map<TypeVariable, AnnotatedTypeMirror> result, ExpressionTree invocation, ExecutableType methodType, AnnotatedTypeFactory factory) If the type arguments computed by DefaultTypeArgumentInference don't match the return type mirror ofinvocation
, then replace those type arguments with an uninferred wildcard.static AnnotationMirrorMap<AnnotationMirror>
createHierarchyMap
(AnnotationMirrorSet annos, QualifierHierarchy qualHierarchy) Take a set of annotations and separate them into a mapping ofhierarchy top => annotations in hierarchy
.static List<AnnotatedTypeMirror>
getArgumentTypes
(ExpressionTree methodInvocation, AnnotatedTypeFactory typeFactory) Returns a list of boxed annotated types corresponding to the arguments inmethodInvocation
.static boolean
isATarget
(AnnotatedTypeMirror type, Set<TypeVariable> targetTypeVars) Given a set of type variables for which we are inferring a type, returns true if type is a use of a type variable in the list of targetTypeVars.static AnnotatedTypeMirror
leastUpperBound
(AnnotatedTypeFactory typeFactory, Iterable<AnnotatedTypeMirror> types) Successively calls least upper bound on the elements of types.static Set<TypeVariable>
Given an AnnotatedExecutableType return a set of type variables that represents the generic type parameters of that method.static AnnotatedTypeMirror
substitute
(Map<TypeVariable, AnnotatedTypeMirror> substitutions, AnnotatedTypeMirror toModify) Create a copy of toModify.static AnnotatedTypeMirror
substitute
(TypeVariable typeVariable, AnnotatedTypeMirror substitution, AnnotatedTypeMirror toModify) Replace all uses of typeVariable with substitution in a copy of toModify using the normal substitution rules.
-
Constructor Details
-
TypeArgInferenceUtil
public TypeArgInferenceUtil()
-
-
Method Details
-
getArgumentTypes
public static List<AnnotatedTypeMirror> getArgumentTypes(ExpressionTree methodInvocation, AnnotatedTypeFactory typeFactory) Returns a list of boxed annotated types corresponding to the arguments inmethodInvocation
.- Parameters:
methodInvocation
-MethodInvocationTree
orNewClassTree
typeFactory
- type factory- Returns:
- a list of boxed annotated types corresponding to the arguments in
methodInvocation
.
-
isATarget
Given a set of type variables for which we are inferring a type, returns true if type is a use of a type variable in the list of targetTypeVars. -
methodTypeToTargets
public static Set<TypeVariable> methodTypeToTargets(AnnotatedTypeMirror.AnnotatedExecutableType methodType) Given an AnnotatedExecutableType return a set of type variables that represents the generic type parameters of that method. -
assignedTo
public static @Nullable AnnotatedTypeMirror assignedTo(AnnotatedTypeFactory atypeFactory, TreePath path) Returns the annotated type that the leaf of path is assigned to, if it is within an assignment context. Returns the annotated type that the method invocation at the leaf is assigned to. If the result is a primitive, return the boxed version.- Parameters:
atypeFactory
- the type factory, for looking up typespath
- the path whole leaf to look up a type for- Returns:
- the type of path's leaf
-
assignedToVariable
public static AnnotatedTypeMirror assignedToVariable(AnnotatedTypeFactory atypeFactory, VariableTree assignmentContext) If the variable's type is a type variable, return getAnnotatedTypeLhsNoTypeVarDefault(tree). Rationale:For example:
During type argument inference of<S> S bar () {...} <T> T foo(T p) { T local = bar(); return local; }
bar
, the assignment context islocal
. If the local variable default is used, then the type of assignment context type is@Nullable T
and the type argument inferred forbar()
is@Nullable T
. And an incompatible types in return error is issued.If instead, the local variable default is not applied, then the assignment context type is
T
(with lower bound@NonNull Void
and upper bound@Nullable Object
) and the type argument inferred forbar()
isT
. During dataflow, the type oflocal
is refined toT
and the return is legal.If the assignment context type was a declared type, for example:
The local variable default must be used or else the assignment context type is missing an annotation. So, an incompatible types in return error is issued in the above code. We could improve type argument inference in this case and by using the lower bound of<S> S bar () {...} Object foo() { Object local = bar(); return local; }
S
instead of the local variable default.- Parameters:
atypeFactory
- the type factoryassignmentContext
- VariableTree- Returns:
- AnnotatedTypeMirror of Assignment context
-
containsTypeParameter
public static boolean containsTypeParameter(AnnotatedTypeMirror type, Collection<TypeVariable> typeVariables) Returns true iftype
contains a use of a type variable intypeVariables
.- Parameters:
type
- type to searchtypeVariables
- collection of type variables- Returns:
- true if
type
contains a use of a type variable intypeVariables
-
createHierarchyMap
public static AnnotationMirrorMap<AnnotationMirror> createHierarchyMap(AnnotationMirrorSet annos, QualifierHierarchy qualHierarchy) Take a set of annotations and separate them into a mapping ofhierarchy top => annotations in hierarchy
. -
checkForUninferredTypes
Throws an exception if the type is an uninferred type argument.The error will be caught in DefaultTypeArgumentInference#infer and inference will be aborted, but type-checking will continue.
-
substitute
public static AnnotatedTypeMirror substitute(TypeVariable typeVariable, AnnotatedTypeMirror substitution, AnnotatedTypeMirror toModify) Replace all uses of typeVariable with substitution in a copy of toModify using the normal substitution rules. Return the copy- See Also:
-
substitute
public static AnnotatedTypeMirror substitute(Map<TypeVariable, AnnotatedTypeMirror> substitutions, AnnotatedTypeMirror toModify) Create a copy of toModify. In the copy, for each pairtypeVariable => annotated type
replace uses of typeVariable with the corresponding annotated type using normal substitution rules (@see TypeVariableSubstitutor). Return the copy. -
leastUpperBound
public static AnnotatedTypeMirror leastUpperBound(AnnotatedTypeFactory typeFactory, Iterable<AnnotatedTypeMirror> types) Successively calls least upper bound on the elements of types. Unlike leastUpperBound, this method will box primitives if necessary -
correctResults
protected static Map<TypeVariable,AnnotatedTypeMirror> correctResults(Map<TypeVariable, AnnotatedTypeMirror> result, ExpressionTree invocation, ExecutableType methodType, AnnotatedTypeFactory factory) If the type arguments computed by DefaultTypeArgumentInference don't match the return type mirror ofinvocation
, then replace those type arguments with an uninferred wildcard.
-