use of org.eclipse.jdt.internal.compiler.lookup.ParameterizedMethodBinding in project bazel-jdt-java-toolchain by salesforce.
the class ASTNode method resolvePolyExpressionArguments.
/**
* After method lookup has produced 'methodBinding' but when poly expressions have been seen as arguments,
* inspect the arguments to trigger another round of resolving with improved target types from the methods parameters.
* If this resolving produces better types for any arguments, update the 'argumentTypes' array in-place as an
* intended side effect that will feed better type information in checkInvocationArguments() and others.
* @param invocation the outer invocation which is being resolved
* @param method the method produced by lookup (possibly involving type inference).
* @param argumentTypes the argument types as collected from first resolving the invocation arguments and as used for the method lookup.
* @param scope scope for resolution.
* @return either the original method or a problem method
*/
public static MethodBinding resolvePolyExpressionArguments(Invocation invocation, MethodBinding method, TypeBinding[] argumentTypes, BlockScope scope) {
MethodBinding candidateMethod = method.isValidBinding() ? method : method instanceof ProblemMethodBinding ? ((ProblemMethodBinding) method).closestMatch : null;
if (candidateMethod == null)
return method;
ProblemMethodBinding problemMethod = null;
boolean variableArity = candidateMethod.isVarargs();
final TypeBinding[] parameters = candidateMethod.parameters;
Expression[] arguments = invocation.arguments();
if (variableArity && arguments != null && parameters.length == arguments.length) {
if (arguments[arguments.length - 1].isCompatibleWith(parameters[parameters.length - 1], scope)) {
variableArity = false;
}
}
for (int i = 0, length = arguments == null ? 0 : arguments.length; i < length; i++) {
Expression argument = arguments[i];
TypeBinding parameterType = InferenceContext18.getParameter(parameters, i, variableArity);
if (parameterType == null)
// not much we can do without a target type, assume it only happens after some resolve error
continue;
if (argumentTypes[i] != null && argumentTypes[i].isPolyType()) {
argument.setExpectedType(parameterType);
TypeBinding updatedArgumentType;
if (argument instanceof LambdaExpression) {
LambdaExpression lambda = (LambdaExpression) argument;
// avoid complaining about non-kosher descriptor as secondary problem
boolean skipKosherCheck = method.problemId() == ProblemReasons.Ambiguous;
updatedArgumentType = lambda.resolveType(scope, skipKosherCheck);
// additional checks, because LE.resolveType may return a valid binding even in the presence of structural errors
if (lambda.hasErrors() || lambda.hasDescripterProblem) {
continue;
}
// avoid that preliminary local type bindings escape beyond this point:
lambda.updateLocalTypesInMethod(candidateMethod);
// refresh after update
parameterType = InferenceContext18.getParameter(parameters, i, variableArity);
if (!lambda.isCompatibleWith(parameterType, scope)) {
if (method.isValidBinding() && problemMethod == null) {
TypeBinding[] originalArguments = Arrays.copyOf(argumentTypes, argumentTypes.length);
if (lambda.reportShapeError(parameterType, scope)) {
problemMethod = new ProblemMethodBinding(candidateMethod, method.selector, originalArguments, ProblemReasons.ErrorAlreadyReported);
} else {
problemMethod = new ProblemMethodBinding(candidateMethod, method.selector, originalArguments, ProblemReasons.NotFound);
}
}
continue;
}
} else {
updatedArgumentType = argument.resolveType(scope);
}
if (updatedArgumentType != null && updatedArgumentType.kind() != Binding.POLY_TYPE) {
argumentTypes[i] = updatedArgumentType;
if (candidateMethod.isPolymorphic())
candidateMethod.parameters[i] = updatedArgumentType;
}
}
}
if (method.returnType instanceof ReferenceBinding) {
scope.referenceCompilationUnit().updateLocalTypesInMethod(method);
}
if (method instanceof ParameterizedGenericMethodBinding) {
InferenceContext18 ic18 = invocation.getInferenceContext((ParameterizedMethodBinding) method);
if (ic18 != null)
// overload resolution is done, now perform the push of bounds from inner to outer
ic18.flushBoundOutbox();
}
if (problemMethod != null)
return problemMethod;
return method;
}
Aggregations