Class InferenceContext18

java.lang.Object
org.aspectj.org.eclipse.jdt.internal.compiler.lookup.InferenceContext18

public class InferenceContext18 extends Object
Main class for new type inference as per JLS8 sect 18. Keeps contextual state and drives the algorithm.

Inference Basics

  • 18.1.1 Inference variables: InferenceVariable
  • 18.1.2 Constraint Formulas: subclasses of ConstraintFormula
  • 18.1.3 Bounds: TypeBound
    Capture bounds are directly captured in BoundSet.captures, throws-bounds in BoundSet.inThrows.
    Also: BoundSet: main state during inference.
Each instance of InferenceContext18 manages instances of the above and coordinates the inference process.

Queries and utilities

  • TypeBinding.isProperType(boolean): used to exclude "types" that mention inference variables (18.1.1).
  • TypeBinding.mentionsAny(TypeBinding[], int): does the receiver type binding mention any of the given types?
  • TypeBinding.substituteInferenceVariable(InferenceVariable, TypeBinding): replace occurrences of an inference variable with a proper type.
  • TypeBinding.collectInferenceVariables(Set): collect all inference variables mentioned in the receiver type into the given set.
  • TypeVariableBinding.getTypeBounds(InferenceVariable, InferenceSubstitution): Compute the initial type bounds for one inference variable as per JLS8 sect 18.1.3.

Phases of Inference

  • 18.2 Reduction: reduce() with most work happening in implementations of ConstraintFormula.reduce(InferenceContext18):
    • 18.2.1 Expression Compatibility Constraints: ConstraintFormula.reduce(InferenceContext18).
    • 18.2.2 Type Compatibility Constraints ff. ConstraintFormula.reduce(InferenceContext18).
  • 18.3 Incorporation: BoundSet.incorporate(InferenceContext18); during inference new constraints are accepted via BoundSet.reduceOneConstraint(InferenceContext18, ConstraintFormula) (combining 18.2 and 18.3)
  • 18.4 Resolution: resolve(InferenceVariable[]).
Some of the above operations accumulate their results into currentBounds, whereas the last phase returns the resulting bound set while keeping the previous state in currentBounds.

18.5. Uses of Inference

These are the main entries from the compiler into the inference engine:
18.5.1 Invocation Applicability Inference
inferInvocationApplicability(MethodBinding, TypeBinding[], boolean). Prepare the initial state for inference of a generic invocation - no target type used at this point. Need to call solve(boolean) with true afterwards to produce the intermediate result.
Called indirectly from Scope.findMethod(ReferenceBinding, char[], TypeBinding[], InvocationSite, boolean) et al to select applicable methods into overload resolution.
18.5.2 Invocation Type Inference
inferInvocationType(TypeBinding, InvocationSite, MethodBinding). After a most specific method has been picked, and given a target type determine the final generic instantiation. As long as a target type is still unavailable this phase keeps getting deferred.
Different wrappers exist for the convenience of different callers.
18.5.3 Functional Interface Parameterization Inference
Controlled from FunctionalExpression.resolveType(BlockScope).
18.5.4 More Specific Method Inference
Not Yet Implemented
For 18.5.1 and 18.5.2 high-level control is implemented in ParameterizedGenericMethodBinding.computeCompatibleMethod(MethodBinding, TypeBinding[], Scope, InvocationSite).

Inference Lifecycle

  • Decision whether or not an invocation is a variable-arity invocation is made by first attempting to solve 18.5.1 in mode CHECK_LOOSE. Only if that fails, another attempt is made in mode CHECK_VARARG. Which of these two attempts was successful is stored in inferenceKind. This field must be consulted whenever arguments of an invocation should be further processed. See also getParameter(TypeBinding[], int, boolean) and its clients.