org.aspectj.org.eclipse.jdt.internal.compiler.lookup
Class InferenceContext18

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

public class InferenceContext18
extends java.lang.Object

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

Inference Basics

Each instance of InferenceContext18 manages instances of the above and coordinates the inference process.

Queries and utilities

Phases of Inference

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() 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(BoundSet, 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 LambdaExpression.resolveType(BlockScope).
18.5.4 More Specific Method Inference
Not Yet Implemented
For 18.5.1 and 18.5.2 some high-level control is implemented in ParameterizedGenericMethodBinding.computeCompatibleMethod(MethodBinding, TypeBinding[], Scope, InvocationSite, int).

Inference Lifecycle

The separation into 18.5.1 and 18.5.2 causes some complexity:


Field Summary
static int APPLICABILITY_INFERRED
          Applicability Inference (18.5.1) has been completed.
static int BINDINGS_UPDATED
          All nested elements have been fully resolved.
static int CHECK_LOOSE
           
static int CHECK_STRICT
           
static int CHECK_VARARG
           
 java.util.List<org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ConstraintFormula> constraintsWithUncheckedConversion
          Signals whether any type compatibility makes use of unchecked conversion.
static int NOT_INFERRED
           
 InferenceContext18 outerContext
          Link to an outer inference context, used for bundled error reporting.
 int stepCompleted
          Marks how much work has been done so far? Used to avoid performing any of these tasks more than once.
static int TYPE_INFERRED
          Invocation Type Inference (18.5.2) has been completed (for some target type).
 
Constructor Summary
InferenceContext18(Scope scope)
           
InferenceContext18(Scope scope, Expression[] arguments, InvocationSite site)
          Construct an inference context for an invocation (method/constructor).
 
Method Summary
 void addProblemMethod(ProblemMethodBinding problemMethod)
           
 void addThrowsContraints(TypeBinding[] parameters, InferenceVariable[] variables, ReferenceBinding[] thrownExceptions)
          JLS 18.1.3 Bounds: throws α: the inference variable α appears in a throws clause
 InferenceVariable[] addTypeVariableSubstitutions(TypeBinding[] typeVariables)
          Add new inference variables for the given type variables.
 InferenceVariable[] createInitialBoundSet(TypeVariableBinding[] typeParameters)
          JLS 18.1.3: Create initial bounds from a given set of type parameters declarations.
 void createInitialConstraintsForParameters(TypeBinding[] parameters, boolean checkVararg, TypeBinding varArgsType, MethodBinding method)
          JLS 18.5.1: compute bounds from formal and actual parameters.
 org.aspectj.org.eclipse.jdt.internal.compiler.lookup.InferenceContext18.SuspendedInferenceRecord enterLambda(LambdaExpression lambda)
           
 org.aspectj.org.eclipse.jdt.internal.compiler.lookup.InferenceContext18.SuspendedInferenceRecord enterPolyInvocation(InvocationSite invocation, Expression[] innerArguments)
           
 TypeBinding[] getFunctionInterfaceArgumentSolutions(TypeBinding[] a)
           
static TypeBinding getParameter(TypeBinding[] parameters, int rank, boolean isVarArgs)
          Retrieve the rank'th parameter, possibly respecting varargs invocation, see 15.12.2.4.
 MethodBinding getReturnProblemMethodIfNeeded(TypeBinding expectedType, MethodBinding method)
          Create a problem method signaling failure of invocation type inference, unless the given candidate is tolerable to be compatible with buggy javac.
 TypeBinding[] getSolutions(TypeVariableBinding[] typeParameters, InvocationSite site, org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BoundSet boundSet)
          Retrieve the resolved solutions for all given type variables.
 boolean hasResultFor(TypeBinding targetType)
           
 ReferenceBinding inferFunctionalInterfaceParameterization(LambdaExpression lambda, BlockScope blockScope, ParameterizedTypeBinding targetTypeWithWildCards)
          18.5.3 Functional Interface Parameterization Inference
 void inferInvocationApplicability(MethodBinding method, TypeBinding[] arguments, boolean isDiamond)
          JLS 18.5.1 Invocation Applicability Inference.
 org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BoundSet inferInvocationType(org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BoundSet b1, TypeBinding expectedType, InvocationSite invocationSite, MethodBinding method)
          JLS 18.5.2 Invocation Type Inference
 MethodBinding inferInvocationType(Invocation invocation, ParameterizedGenericMethodBinding method)
          Simplified API to perform Invocation Type Inference (JLS 18.5.2) and perform subsequent steps: bound check, rebinding of inner poly expressions, and creating of a problem method binding if needed.
 boolean isMoreSpecificThan(MethodBinding m1, MethodBinding m2, boolean isVarArgs, boolean isVarArgs2)
          18.5.4 More Specific Method Inference
 boolean isResolved(org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BoundSet boundSet)
          Have all inference variables been instantiated successfully?
 boolean isVarArgs()
           
static void missingImplementation(java.lang.String msg)
           
static ParameterizedTypeBinding parameterizedWithWildcard(TypeBinding type)
          If 'type' is a parameterized type and one of its arguments is a wildcard answer the casted type, else null.
 void rebindInnerPolies(org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BoundSet bounds, TypeBinding[] parameterTypes)
          After inference has finished, iterate all inner poly expressions (Invocations), that have been included in the inference.
 boolean rebindInnerPolies(MethodBinding method, InvocationSite site)
           
 void recordUncheckedConversion(org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ConstraintTypeFormula constraint)
          Record the fact that the given constraint requires unchecked conversion.
 boolean reduceAndIncorporate(org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ConstraintFormula constraint)
          When inference produces a new constraint, reduce it to a suitable type bound and add the latter to the bound set.
 boolean reduceWithEqualityConstraints(TypeBinding[] p, TypeBinding[] q)
           
 boolean registerSolution(TypeBinding targetType, MethodBinding updatedBinding)
           
 void reportInvalidInvocation(Invocation invocation, MethodBinding binding)
           
 void resumeSuspendedInference(org.aspectj.org.eclipse.jdt.internal.compiler.lookup.InferenceContext18.SuspendedInferenceRecord record)
           
 org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BoundSet solve()
          Try to solve the inference problem defined by constraints and bounds previously registered.
 org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BoundSet solve(InferenceVariable[] toResolve)
           
 TypeBinding substitute(TypeBinding type)
          Substitute any type variables mentioned in 'type' by the corresponding inference variable, if one exists.
 java.lang.String toString()
           
 boolean usesUncheckedConversion()
          For use by 15.12.2.6 Method Invocation Type
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

stepCompleted

public int stepCompleted
Marks how much work has been done so far? Used to avoid performing any of these tasks more than once.


NOT_INFERRED

public static final int NOT_INFERRED
See Also:
Constant Field Values

APPLICABILITY_INFERRED

public static final int APPLICABILITY_INFERRED
Applicability Inference (18.5.1) has been completed.

See Also:
Constant Field Values

TYPE_INFERRED

public static final int TYPE_INFERRED
Invocation Type Inference (18.5.2) has been completed (for some target type).

See Also:
Constant Field Values

BINDINGS_UPDATED

public static final int BINDINGS_UPDATED
All nested elements have been fully resolved.

See Also:
Constant Field Values

constraintsWithUncheckedConversion

public java.util.List<org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ConstraintFormula> constraintsWithUncheckedConversion
Signals whether any type compatibility makes use of unchecked conversion.


outerContext

public InferenceContext18 outerContext
Link to an outer inference context, used for bundled error reporting.


CHECK_STRICT

public static final int CHECK_STRICT
See Also:
Constant Field Values

CHECK_LOOSE

public static final int CHECK_LOOSE
See Also:
Constant Field Values

CHECK_VARARG

public static final int CHECK_VARARG
See Also:
Constant Field Values
Constructor Detail

InferenceContext18

public InferenceContext18(Scope scope,
                          Expression[] arguments,
                          InvocationSite site)
Construct an inference context for an invocation (method/constructor).


InferenceContext18

public InferenceContext18(Scope scope)
Method Detail

createInitialBoundSet

public InferenceVariable[] createInitialBoundSet(TypeVariableBinding[] typeParameters)
JLS 18.1.3: Create initial bounds from a given set of type parameters declarations.

Returns:
the set of inference variables created for the given typeParameters

substitute

public TypeBinding substitute(TypeBinding type)
Substitute any type variables mentioned in 'type' by the corresponding inference variable, if one exists.


createInitialConstraintsForParameters

public void createInitialConstraintsForParameters(TypeBinding[] parameters,
                                                  boolean checkVararg,
                                                  TypeBinding varArgsType,
                                                  MethodBinding method)
JLS 18.5.1: compute bounds from formal and actual parameters.


addTypeVariableSubstitutions

public InferenceVariable[] addTypeVariableSubstitutions(TypeBinding[] typeVariables)
Add new inference variables for the given type variables.


addThrowsContraints

public void addThrowsContraints(TypeBinding[] parameters,
                                InferenceVariable[] variables,
                                ReferenceBinding[] thrownExceptions)
JLS 18.1.3 Bounds: throws α: the inference variable α appears in a throws clause


inferInvocationApplicability

public void inferInvocationApplicability(MethodBinding method,
                                         TypeBinding[] arguments,
                                         boolean isDiamond)
JLS 18.5.1 Invocation Applicability Inference.


inferInvocationType

public org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BoundSet inferInvocationType(org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BoundSet b1,
                                                                                         TypeBinding expectedType,
                                                                                         InvocationSite invocationSite,
                                                                                         MethodBinding method)
                                                                                  throws InferenceFailureException
JLS 18.5.2 Invocation Type Inference

Callers are responsible for any post-processing (see rebindInnerPolies(BoundSet, TypeBinding[])).

Parameters:
b1 - "the bound set produced by reduction in order to demonstrate that m is applicable in 18.5.1"
Throws:
InferenceFailureException

inferInvocationType

public MethodBinding inferInvocationType(Invocation invocation,
                                         ParameterizedGenericMethodBinding method)
Simplified API to perform Invocation Type Inference (JLS 18.5.2) and perform subsequent steps: bound check, rebinding of inner poly expressions, and creating of a problem method binding if needed. Should only be called if the inference has not yet finished. Version used for inner invocations, where argument types need to be extracted from actual invocation arguments.

Parameters:
invocation - invocation being inferred
method - current candidate method binding for this invocation
Returns:
a valid method binding with updated type parameters, or a problem method binding signaling either inference failure or a bound mismatch.

hasResultFor

public boolean hasResultFor(TypeBinding targetType)

registerSolution

public boolean registerSolution(TypeBinding targetType,
                                MethodBinding updatedBinding)

inferFunctionalInterfaceParameterization

public ReferenceBinding inferFunctionalInterfaceParameterization(LambdaExpression lambda,
                                                                 BlockScope blockScope,
                                                                 ParameterizedTypeBinding targetTypeWithWildCards)
18.5.3 Functional Interface Parameterization Inference


reduceWithEqualityConstraints

public boolean reduceWithEqualityConstraints(TypeBinding[] p,
                                             TypeBinding[] q)

isMoreSpecificThan

public boolean isMoreSpecificThan(MethodBinding m1,
                                  MethodBinding m2,
                                  boolean isVarArgs,
                                  boolean isVarArgs2)
18.5.4 More Specific Method Inference


solve

public org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BoundSet solve()
                                                                    throws InferenceFailureException
Try to solve the inference problem defined by constraints and bounds previously registered.

Returns:
a bound set representing the solution, or null if inference failed
Throws:
InferenceFailureException - a compile error has been detected during inference

solve

public org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BoundSet solve(InferenceVariable[] toResolve)
                                                                    throws InferenceFailureException
Throws:
InferenceFailureException

isResolved

public boolean isResolved(org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BoundSet boundSet)
Have all inference variables been instantiated successfully?


getSolutions

public TypeBinding[] getSolutions(TypeVariableBinding[] typeParameters,
                                  InvocationSite site,
                                  org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BoundSet boundSet)
Retrieve the resolved solutions for all given type variables.

Parameters:
typeParameters -
boundSet - where instantiations are to be found
Returns:
array containing the substituted types or null elements for any type variable that could not be substituted.

reduceAndIncorporate

public boolean reduceAndIncorporate(org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ConstraintFormula constraint)
                             throws InferenceFailureException
When inference produces a new constraint, reduce it to a suitable type bound and add the latter to the bound set.

Throws:
InferenceFailureException

enterPolyInvocation

public org.aspectj.org.eclipse.jdt.internal.compiler.lookup.InferenceContext18.SuspendedInferenceRecord enterPolyInvocation(InvocationSite invocation,
                                                                                                                            Expression[] innerArguments)

enterLambda

public org.aspectj.org.eclipse.jdt.internal.compiler.lookup.InferenceContext18.SuspendedInferenceRecord enterLambda(LambdaExpression lambda)

resumeSuspendedInference

public void resumeSuspendedInference(org.aspectj.org.eclipse.jdt.internal.compiler.lookup.InferenceContext18.SuspendedInferenceRecord record)

rebindInnerPolies

public boolean rebindInnerPolies(MethodBinding method,
                                 InvocationSite site)

rebindInnerPolies

public void rebindInnerPolies(org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BoundSet bounds,
                              TypeBinding[] parameterTypes)
After inference has finished, iterate all inner poly expressions (Invocations), that have been included in the inference. For each of these update some type information from the inference result and perhaps trigger follow-up resolving as needed. Similar for poly expressions that did not directly participate in the inference but are direct arguments of the current invocation (FunctionalExpression, ConditionalExpression).


isVarArgs

public boolean isVarArgs()

getParameter

public static TypeBinding getParameter(TypeBinding[] parameters,
                                       int rank,
                                       boolean isVarArgs)
Retrieve the rank'th parameter, possibly respecting varargs invocation, see 15.12.2.4. Returns null if out of bounds and CHECK_VARARG was not requested. Precondition: isVarArgs implies method.isVarargs()


getReturnProblemMethodIfNeeded

public MethodBinding getReturnProblemMethodIfNeeded(TypeBinding expectedType,
                                                    MethodBinding method)
Create a problem method signaling failure of invocation type inference, unless the given candidate is tolerable to be compatible with buggy javac.


reportInvalidInvocation

public void reportInvalidInvocation(Invocation invocation,
                                    MethodBinding binding)

toString

public java.lang.String toString()
Overrides:
toString in class java.lang.Object

addProblemMethod

public void addProblemMethod(ProblemMethodBinding problemMethod)

parameterizedWithWildcard

public static ParameterizedTypeBinding parameterizedWithWildcard(TypeBinding type)
If 'type' is a parameterized type and one of its arguments is a wildcard answer the casted type, else null. A nonnull answer is ensured to also have nonnull arguments.


getFunctionInterfaceArgumentSolutions

public TypeBinding[] getFunctionInterfaceArgumentSolutions(TypeBinding[] a)

recordUncheckedConversion

public void recordUncheckedConversion(org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ConstraintTypeFormula constraint)
Record the fact that the given constraint requires unchecked conversion.


usesUncheckedConversion

public boolean usesUncheckedConversion()
For use by 15.12.2.6 Method Invocation Type


missingImplementation

public static void missingImplementation(java.lang.String msg)