Class InvocationTypeInference
infer(ExpressionTree, AnnotatedExecutableType)
Invocation type inference is the process by which method type arguments are inferred for a given method invocation. An overview of the process is given below.
1. Inference creates an inference variable for each method type argument for a given method invocation. Each inference variable may have zero or more upper, lower, and equal bounds. The bounds of an inference variable are initially the bounds on the type argument. More bounds may be infered in later steps.
Bounds are between an inference variable and an abstract type. AbstractType
s are
type-like structures that might include inference variables. Abstract types might also be an
inference variable or a type without any inference variables, which is also know as a proper
type.
An inference variable is represented by a Variable
object which holds bounds for the
inference variable, in an VariableBounds
object. Additional
inference variables may be created in later steps if any subexpression of the method invocation
requires type inference.
2. Next, inference creates constraints between the arguments to the method invocation and its formal parameters. Also, for non-void methods, a constraint between the declared return type and the "target type" of the method invocation is created. "Target types" are defined in JLS Chapter 5. For example, the target type of a method invocation assigned to a variable is the type of the variable.
Constraints are represented by TypeConstraint
objects and are between abstract types
(see AbstractType
) and either expressions (see Expression
) or other abstract
types. A constraint might also be an abstract type that might be thrown by the method invocation
(see CheckedExceptionConstraint
). Groups of constraints are stored in ConstraintSet
s.
3. Next, these constraints are "reduced" producing bounds on the inference variables.
Reduction depends on the kind of constraint and is defined in JLS section
18.2. In this code base, constraints are reduced via ConstraintSet.reduce(Java8InferenceContext)
.
4. The inference variables' bounds are then "incorporated" which produces more bounds and/or
constraints that must then be "reduced" or "incorporated". Incorporation and reduction continue
until no new bounds or constraints are produced. Bounds are incorporated via BoundSet.incorporateToFixedPoint(BoundSet)
. Incorporation in defined in JLS section
18.3.
5. Finally, a type for each inference variable is computed by "resolving" the bounds.
Variables are resolved via Resolution.resolve(Collection, BoundSet, Java8InferenceContext)
. Resolution is defined in the JLS section
18.4.
An object of this class stores information about some particular invocation that requires inference.
-
Field Summary
Modifier and TypeFieldDescriptionprotected final SourceChecker
Checker used to issue errors/warnings.protected final Java8InferenceContext
Stores information about the current inference problem being solved.protected final Tree
Tree for which type arguments are being inferred. -
Constructor Summary
ConstructorDescriptionInvocationTypeInference
(AnnotatedTypeFactory factory, TreePath pathToExpression) Creates an inference problem. -
Method Summary
Modifier and TypeMethodDescriptioncreateB2
(InvocationType methodType, List<? extends ExpressionTree> args, Theta map) Creates the bound set used to determine whether a method is applicable.createB2MethodRef
(InvocationType methodType, List<AbstractType> args, Theta map) Same ascreateB2(InvocationType, List, Theta)
, but for method references.createB3
(BoundSet b2, ExpressionTree invocation, InvocationType methodType, AbstractType target, Theta map) Creates constraints against the target type ofinvocation
and then reduces and incorporates those constraints withb2
.createC
(InvocationType methodType, List<? extends ExpressionTree> args, Theta map) Creates the constraints between the formal parameters and arguments that are not pertinent to applicability.Returns the tree for which inference is being inferred.infer
(ExpressionTree invocation, AnnotatedTypeMirror.AnnotatedExecutableType methodType) Perform invocation type inference oninvocation
.infer
(MemberReferenceTree invocation) Perform invocation type inference oninvocation
.
-
Field Details
-
checker
Checker used to issue errors/warnings. -
context
Stores information about the current inference problem being solved. -
inferenceExpression
Tree for which type arguments are being inferred.
-
-
Constructor Details
-
InvocationTypeInference
Creates an inference problem.- Parameters:
factory
- the annotated type factory to usepathToExpression
- path to the expression for which inference is preformed
-
-
Method Details
-
getInferenceExpression
Returns the tree for which inference is being inferred.- Returns:
- the tree for which inference is being inferred
-
infer
public InferenceResult infer(ExpressionTree invocation, AnnotatedTypeMirror.AnnotatedExecutableType methodType) throws FalseBoundException Perform invocation type inference oninvocation
. See JLS 18.5.2.- Parameters:
invocation
- invocation which needs inferencemethodType
- type of the method invocation- Returns:
- the result of inference
- Throws:
FalseBoundException
- if inference fails because of the java types
-
infer
Perform invocation type inference oninvocation
. See JLS 18.5.2.- Parameters:
invocation
- member reference tree- Returns:
- the result of inference
- Throws:
FalseBoundException
- if inference fails because of the java types
-
createB2
Creates the bound set used to determine whether a method is applicable. This method is called B2 in JLS Section 18.5.1.It does this by:
- Creating the inference variables and initializing their bounds based on the type parameter declaration.
- Adding any bounds implied by the throws clause of
methodType
. - Constructing constraints between formal parameters and arguments that are "pertinent to applicability" (See JLS Section 15.12.2.2). Generally, all arguments are applicable except: inexact method reference, implicitly typed lambdas, or explicitly typed lambda whose return expression(s) are not pertinent.
- Reducing and incorporating those constraints which finally produces B2.
- Parameters:
methodType
- the type of the method or constructor invokedargs
- argument expression tressmap
- map of type variables to (inference) variables- Returns:
- bound set used to determine whether a method is applicable
-
createB2MethodRef
Same ascreateB2(InvocationType, List, Theta)
, but for method references. A list of types is used instead of a list of arguments. These types are the types of the formal parameters of function type of target type of the method reference.- Parameters:
methodType
- the type of the method or constructor invokedargs
- types to use as argumentsmap
- map of type variables to (inference) variables- Returns:
- bound set used to determine whether a method is applicable
-
createB3
public BoundSet createB3(BoundSet b2, ExpressionTree invocation, InvocationType methodType, AbstractType target, Theta map) Creates constraints against the target type ofinvocation
and then reduces and incorporates those constraints withb2
. (See JLS 18.5.2.1.)- Parameters:
b2
- BoundSet created bycreateB2(InvocationType, List, Theta)
invocation
- a method or constructor invocationmethodType
- the type of the method or constructor invoked by expressiontarget
- target type of the invocationmap
- map of type variables to (inference) variables- Returns:
- bound set created by constraints against the target type of the invocation
-
createC
public ConstraintSet createC(InvocationType methodType, List<? extends ExpressionTree> args, Theta map) Creates the constraints between the formal parameters and arguments that are not pertinent to applicability. (See JLS 18.5.2.2.)- Parameters:
methodType
- type of method invokedargs
- argument expression treesmap
- map from type variable to inference variable- Returns:
- the constraints between the formal parameters and arguments that are not pertinent to applicability
-