Search in sources :

Example 1 with ParameterizedMethodBinding

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;
}
Also used : InferenceContext18(org.eclipse.jdt.internal.compiler.lookup.InferenceContext18) ProblemMethodBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding) SourceTypeBinding(org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding) TypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding) ParameterizedGenericMethodBinding(org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding) ProblemMethodBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding) MethodBinding(org.eclipse.jdt.internal.compiler.lookup.MethodBinding) ParameterizedMethodBinding(org.eclipse.jdt.internal.compiler.lookup.ParameterizedMethodBinding) ParameterizedGenericMethodBinding(org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding) ReferenceBinding(org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding)

Aggregations

InferenceContext18 (org.eclipse.jdt.internal.compiler.lookup.InferenceContext18)1 MethodBinding (org.eclipse.jdt.internal.compiler.lookup.MethodBinding)1 ParameterizedGenericMethodBinding (org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding)1 ParameterizedMethodBinding (org.eclipse.jdt.internal.compiler.lookup.ParameterizedMethodBinding)1 ProblemMethodBinding (org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding)1 ReferenceBinding (org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding)1 SourceTypeBinding (org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding)1 TypeBinding (org.eclipse.jdt.internal.compiler.lookup.TypeBinding)1