Search in sources :

Example 1 with ParameterizedGenericMethodBinding

use of org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding 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)

Example 2 with ParameterizedGenericMethodBinding

use of org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding in project bazel-jdt-java-toolchain by salesforce.

the class LambdaExpression method updateLocalTypesInMethod.

public static void updateLocalTypesInMethod(MethodBinding method, Substitutor substor, Substitution subst) {
    method.declaringClass = (ReferenceBinding) substor.substitute(subst, method.declaringClass);
    method.returnType = substor.substitute(subst, method.returnType);
    for (int i = 0; i < method.parameters.length; i++) {
        method.parameters[i] = substor.substitute(subst, method.parameters[i]);
    }
    if (method instanceof ParameterizedGenericMethodBinding) {
        ParameterizedGenericMethodBinding pgmb = (ParameterizedGenericMethodBinding) method;
        for (int i = 0; i < pgmb.typeArguments.length; i++) {
            pgmb.typeArguments[i] = substor.substitute(subst, pgmb.typeArguments[i]);
        }
    }
}
Also used : ParameterizedGenericMethodBinding(org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding)

Example 3 with ParameterizedGenericMethodBinding

use of org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding in project bazel-jdt-java-toolchain by salesforce.

the class ProblemReporter method invalidMethod.

public void invalidMethod(MessageSend messageSend, MethodBinding method, Scope scope) {
    if (isRecoveredName(messageSend.selector))
        return;
    // default...
    int id = IProblem.UndefinedMethod;
    MethodBinding shownMethod = method;
    switch(method.problemId()) {
        case ProblemReasons.ErrorAlreadyReported:
            return;
        case ProblemReasons.NoSuchMethodOnArray:
            // secondary error.
            return;
        case ProblemReasons.NotFound:
            if ((method.declaringClass.tagBits & TagBits.HasMissingType) != 0) {
                this.handle(IProblem.UndefinedType, new String[] { new String(method.declaringClass.readableName()) }, new String[] { new String(method.declaringClass.shortReadableName()) }, messageSend.receiver.sourceStart, messageSend.receiver.sourceEnd);
                return;
            }
            id = IProblem.UndefinedMethod;
            ProblemMethodBinding problemMethod = (ProblemMethodBinding) method;
            if (problemMethod.closestMatch != null) {
                shownMethod = problemMethod.closestMatch;
                if ((shownMethod.tagBits & TagBits.HasMissingType) != 0) {
                    missingTypeInMethod(messageSend, shownMethod);
                    return;
                }
                String closestParameterTypeNames = typesAsString(shownMethod, false);
                String parameterTypeNames = typesAsString(problemMethod.parameters, false);
                String closestParameterTypeShortNames = typesAsString(shownMethod, true);
                String parameterTypeShortNames = typesAsString(problemMethod.parameters, true);
                if (closestParameterTypeNames.equals(parameterTypeNames)) {
                    // include null annotations, maybe they show the difference:
                    closestParameterTypeNames = typesAsString(shownMethod, false, true);
                    parameterTypeNames = typesAsString(problemMethod.parameters, false, true);
                    closestParameterTypeShortNames = typesAsString(shownMethod, true, true);
                    parameterTypeShortNames = typesAsString(problemMethod.parameters, true, true);
                }
                if (closestParameterTypeShortNames.equals(parameterTypeShortNames)) {
                    closestParameterTypeShortNames = closestParameterTypeNames;
                    parameterTypeShortNames = parameterTypeNames;
                }
                this.handle(IProblem.ParameterMismatch, new String[] { new String(shownMethod.declaringClass.readableName()), new String(shownMethod.selector), closestParameterTypeNames, parameterTypeNames }, new String[] { new String(shownMethod.declaringClass.shortReadableName()), new String(shownMethod.selector), closestParameterTypeShortNames, parameterTypeShortNames }, (int) (messageSend.nameSourcePosition >>> 32), (int) messageSend.nameSourcePosition);
                return;
            }
            break;
        case ProblemReasons.NotVisible:
        case ProblemReasons.NotAccessible:
            id = (method.problemId() == ProblemReasons.NotVisible) ? IProblem.NotVisibleMethod : IProblem.NotAccessibleMethod;
            problemMethod = (ProblemMethodBinding) method;
            if (problemMethod.closestMatch != null) {
                shownMethod = problemMethod.closestMatch.original();
            }
            break;
        case ProblemReasons.Ambiguous:
            id = IProblem.AmbiguousMethod;
            break;
        case ProblemReasons.InheritedNameHidesEnclosingName:
            id = IProblem.InheritedMethodHidesEnclosingName;
            break;
        case ProblemReasons.NonStaticReferenceInConstructorInvocation:
            id = IProblem.InstanceMethodDuringConstructorInvocation;
            break;
        case ProblemReasons.NonStaticReferenceInStaticContext:
            id = IProblem.StaticMethodRequested;
            break;
        case ProblemReasons.NonStaticOrAlienTypeReceiver:
            nonStaticOrAlienTypeReceiver(messageSend, method);
            return;
        case ProblemReasons.InterfaceMethodInvocationNotBelow18:
            this.handle(IProblem.InterfaceStaticMethodInvocationNotBelow18, new String[] { new String(method.declaringClass.readableName()), new String(method.selector) }, new String[] { new String(method.declaringClass.shortReadableName()), new String(method.selector) }, (int) (messageSend.nameSourcePosition >>> 32), (int) messageSend.nameSourcePosition);
            return;
        case ProblemReasons.ReceiverTypeNotVisible:
            this.handle(// cannot occur in javadoc comments
            IProblem.NotVisibleType, new String[] { new String(method.declaringClass.readableName()) }, new String[] { new String(method.declaringClass.shortReadableName()) }, messageSend.receiver.sourceStart, messageSend.receiver.sourceEnd);
            return;
        case ProblemReasons.ParameterBoundMismatch:
            problemMethod = (ProblemMethodBinding) method;
            ParameterizedGenericMethodBinding substitutedMethod = (ParameterizedGenericMethodBinding) problemMethod.closestMatch;
            shownMethod = substitutedMethod.original();
            int augmentedLength = problemMethod.parameters.length;
            TypeBinding inferredTypeArgument = problemMethod.parameters[augmentedLength - 2];
            TypeVariableBinding typeParameter = (TypeVariableBinding) problemMethod.parameters[augmentedLength - 1];
            // remove extra info from the end
            TypeBinding[] invocationArguments = new TypeBinding[augmentedLength - 2];
            System.arraycopy(problemMethod.parameters, 0, invocationArguments, 0, augmentedLength - 2);
            this.handle(IProblem.GenericMethodTypeArgumentMismatch, new String[] { new String(shownMethod.selector), typesAsString(shownMethod, false), new String(shownMethod.declaringClass.readableName()), typesAsString(invocationArguments, false), new String(inferredTypeArgument.readableName()), new String(typeParameter.sourceName()), parameterBoundAsString(typeParameter, false) }, new String[] { new String(shownMethod.selector), typesAsString(shownMethod, true), new String(shownMethod.declaringClass.shortReadableName()), typesAsString(invocationArguments, true), new String(inferredTypeArgument.shortReadableName()), new String(typeParameter.sourceName()), parameterBoundAsString(typeParameter, true) }, (int) (messageSend.nameSourcePosition >>> 32), (int) messageSend.nameSourcePosition);
            return;
        case ProblemReasons.TypeParameterArityMismatch:
            problemMethod = (ProblemMethodBinding) method;
            shownMethod = problemMethod.closestMatch;
            if (shownMethod.typeVariables == Binding.NO_TYPE_VARIABLES) {
                this.handle(IProblem.NonGenericMethod, new String[] { new String(shownMethod.selector), typesAsString(shownMethod, false), new String(shownMethod.declaringClass.readableName()), typesAsString(method, false) }, new String[] { new String(shownMethod.selector), typesAsString(shownMethod, true), new String(shownMethod.declaringClass.shortReadableName()), typesAsString(method, true) }, (int) (messageSend.nameSourcePosition >>> 32), (int) messageSend.nameSourcePosition);
            } else {
                this.handle(IProblem.IncorrectArityForParameterizedMethod, new String[] { new String(shownMethod.selector), typesAsString(shownMethod, false), new String(shownMethod.declaringClass.readableName()), typesAsString(shownMethod.typeVariables, false), typesAsString(method, false) }, new String[] { new String(shownMethod.selector), typesAsString(shownMethod, true), new String(shownMethod.declaringClass.shortReadableName()), typesAsString(shownMethod.typeVariables, true), typesAsString(method, true) }, (int) (messageSend.nameSourcePosition >>> 32), (int) messageSend.nameSourcePosition);
            }
            return;
        case ProblemReasons.ParameterizedMethodTypeMismatch:
            problemMethod = (ProblemMethodBinding) method;
            shownMethod = problemMethod.closestMatch;
            this.handle(IProblem.ParameterizedMethodArgumentTypeMismatch, new String[] { new String(shownMethod.selector), typesAsString(shownMethod, false), new String(shownMethod.declaringClass.readableName()), typesAsString(((ParameterizedGenericMethodBinding) shownMethod).typeArguments, false), typesAsString(method, false) }, new String[] { new String(shownMethod.selector), typesAsString(shownMethod, true), new String(shownMethod.declaringClass.shortReadableName()), typesAsString(((ParameterizedGenericMethodBinding) shownMethod).typeArguments, true), typesAsString(method, true) }, (int) (messageSend.nameSourcePosition >>> 32), (int) messageSend.nameSourcePosition);
            return;
        case ProblemReasons.TypeArgumentsForRawGenericMethod:
            problemMethod = (ProblemMethodBinding) method;
            shownMethod = problemMethod.closestMatch;
            this.handle(IProblem.TypeArgumentsForRawGenericMethod, new String[] { new String(shownMethod.selector), typesAsString(shownMethod, false), new String(shownMethod.declaringClass.readableName()), typesAsString(method, false) }, new String[] { new String(shownMethod.selector), typesAsString(shownMethod, true), new String(shownMethod.declaringClass.shortReadableName()), typesAsString(method, true) }, (int) (messageSend.nameSourcePosition >>> 32), (int) messageSend.nameSourcePosition);
            return;
        case ProblemReasons.InferredApplicableMethodInapplicable:
        case ProblemReasons.InvocationTypeInferenceFailure:
            problemMethod = (ProblemMethodBinding) method;
            shownMethod = problemMethod.closestMatch;
            if (problemMethod.returnType == shownMethod.returnType) {
                // $IDENTITY-COMPARISON$
                if (messageSend.expressionContext == ExpressionContext.VANILLA_CONTEXT) {
                    TypeVariableBinding[] typeVariables = method.shallowOriginal().typeVariables;
                    String typeArguments = typesAsString(typeVariables, false);
                    this.handle(IProblem.CannotInferInvocationType, new String[] { typeArguments, String.valueOf(shownMethod.original().readableName()) }, new String[] { typeArguments, String.valueOf(shownMethod.original().shortReadableName()) }, messageSend.sourceStart, messageSend.sourceEnd);
                } else {
                    // FIXME(stephan): turn into an exception once we are sure about this
                    this.handle(IProblem.GenericInferenceError, // $NON-NLS-1$
                    new String[] { "Unknown error at invocation of " + String.valueOf(shownMethod.readableName()) }, // $NON-NLS-1$
                    new String[] { "Unknown error at invocation of " + String.valueOf(shownMethod.shortReadableName()) }, messageSend.sourceStart, messageSend.sourceEnd);
                }
                return;
            }
            TypeBinding shownMethodReturnType = shownMethod.returnType.capture(scope, messageSend.sourceStart, messageSend.sourceEnd);
            this.handle(IProblem.TypeMismatch, new String[] { String.valueOf(shownMethodReturnType.readableName()), // $NON-NLS-1$
            (problemMethod.returnType != null ? String.valueOf(problemMethod.returnType.readableName()) : "<unknown>") }, new String[] { String.valueOf(shownMethodReturnType.shortReadableName()), // $NON-NLS-1$
            (problemMethod.returnType != null ? String.valueOf(problemMethod.returnType.shortReadableName()) : "<unknown>") }, messageSend.sourceStart, messageSend.sourceEnd);
            return;
        case // https://bugs.eclipse.org/bugs/show_bug.cgi?id=346042
        ProblemReasons.VarargsElementTypeNotVisible:
            problemMethod = (ProblemMethodBinding) method;
            if (problemMethod.closestMatch != null) {
                shownMethod = problemMethod.closestMatch.original();
            }
            TypeBinding varargsElementType = shownMethod.parameters[shownMethod.parameters.length - 1].leafComponentType();
            this.handle(IProblem.VarargsElementTypeNotVisible, new String[] { new String(shownMethod.selector), typesAsString(shownMethod, false), new String(shownMethod.declaringClass.readableName()), new String(varargsElementType.readableName()) }, new String[] { new String(shownMethod.selector), typesAsString(shownMethod, true), new String(shownMethod.declaringClass.shortReadableName()), new String(varargsElementType.shortReadableName()) }, (int) (messageSend.nameSourcePosition >>> 32), (int) messageSend.nameSourcePosition);
            return;
        case ProblemReasons.ApplicableMethodOverriddenByInapplicable:
            problemMethod = (ProblemMethodBinding) method;
            if (problemMethod.closestMatch != null) {
                shownMethod = problemMethod.closestMatch.original();
            }
            this.handle(IProblem.ApplicableMethodOverriddenByInapplicable, new String[] { new String(shownMethod.selector), typesAsString(shownMethod, false), new String(shownMethod.declaringClass.readableName()) }, new String[] { new String(shownMethod.selector), typesAsString(shownMethod, true), new String(shownMethod.declaringClass.shortReadableName()) }, (int) (messageSend.nameSourcePosition >>> 32), (int) messageSend.nameSourcePosition);
            return;
        case ProblemReasons.ContradictoryNullAnnotations:
            problemMethod = (ProblemMethodBinding) method;
            contradictoryNullAnnotationsInferred(problemMethod.closestMatch, messageSend);
            return;
        // 0
        case ProblemReasons.NoError:
        default:
            // want to fail to see why we were here...
            needImplementation(messageSend);
            break;
    }
    this.handle(id, new String[] { new String(method.declaringClass.readableName()), new String(shownMethod.selector), typesAsString(shownMethod, false) }, new String[] { new String(method.declaringClass.shortReadableName()), new String(shownMethod.selector), typesAsString(shownMethod, true) }, (int) (messageSend.nameSourcePosition >>> 32), (int) messageSend.nameSourcePosition);
}
Also used : TypeVariableBinding(org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding) ProblemMethodBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding) TypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding) ParameterizedTypeBinding(org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding) SourceTypeBinding(org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding) ParameterizedGenericMethodBinding(org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding) MethodBinding(org.eclipse.jdt.internal.compiler.lookup.MethodBinding) ProblemMethodBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding) ParameterizedGenericMethodBinding(org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding)

Example 4 with ParameterizedGenericMethodBinding

use of org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding in project bazel-jdt-java-toolchain by salesforce.

the class ProblemReporter method javadocInvalidConstructor.

public void javadocInvalidConstructor(Statement statement, MethodBinding targetConstructor, int modifiers) {
    if (!javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers))
        return;
    int sourceStart = statement.sourceStart;
    int sourceEnd = statement.sourceEnd;
    if (statement instanceof AllocationExpression) {
        AllocationExpression allocation = (AllocationExpression) statement;
        if (allocation.enumConstant != null) {
            sourceStart = allocation.enumConstant.sourceStart;
            sourceEnd = allocation.enumConstant.sourceEnd;
        }
    }
    // default...
    int id = IProblem.JavadocUndefinedConstructor;
    ProblemMethodBinding problemConstructor = null;
    MethodBinding shownConstructor = null;
    switch(targetConstructor.problemId()) {
        case ProblemReasons.NotFound:
            id = IProblem.JavadocUndefinedConstructor;
            break;
        case ProblemReasons.NotVisible:
            id = IProblem.JavadocNotVisibleConstructor;
            break;
        case ProblemReasons.Ambiguous:
            id = IProblem.JavadocAmbiguousConstructor;
            break;
        case ProblemReasons.ParameterBoundMismatch:
            int severity = computeSeverity(IProblem.JavadocGenericConstructorTypeArgumentMismatch);
            if (severity == ProblemSeverities.Ignore)
                return;
            problemConstructor = (ProblemMethodBinding) targetConstructor;
            ParameterizedGenericMethodBinding substitutedConstructor = (ParameterizedGenericMethodBinding) problemConstructor.closestMatch;
            shownConstructor = substitutedConstructor.original();
            int augmentedLength = problemConstructor.parameters.length;
            TypeBinding inferredTypeArgument = problemConstructor.parameters[augmentedLength - 2];
            TypeVariableBinding typeParameter = (TypeVariableBinding) problemConstructor.parameters[augmentedLength - 1];
            // remove extra info from the end
            TypeBinding[] invocationArguments = new TypeBinding[augmentedLength - 2];
            System.arraycopy(problemConstructor.parameters, 0, invocationArguments, 0, augmentedLength - 2);
            this.handle(IProblem.JavadocGenericConstructorTypeArgumentMismatch, new String[] { new String(shownConstructor.declaringClass.sourceName()), typesAsString(shownConstructor, false), new String(shownConstructor.declaringClass.readableName()), typesAsString(invocationArguments, false), new String(inferredTypeArgument.readableName()), new String(typeParameter.sourceName()), parameterBoundAsString(typeParameter, false) }, new String[] { new String(shownConstructor.declaringClass.sourceName()), typesAsString(shownConstructor, true), new String(shownConstructor.declaringClass.shortReadableName()), typesAsString(invocationArguments, true), new String(inferredTypeArgument.shortReadableName()), new String(typeParameter.sourceName()), parameterBoundAsString(typeParameter, true) }, severity, sourceStart, sourceEnd);
            return;
        case ProblemReasons.TypeParameterArityMismatch:
            problemConstructor = (ProblemMethodBinding) targetConstructor;
            shownConstructor = problemConstructor.closestMatch;
            boolean noTypeVariables = shownConstructor.typeVariables == Binding.NO_TYPE_VARIABLES;
            severity = computeSeverity(noTypeVariables ? IProblem.JavadocNonGenericConstructor : IProblem.JavadocIncorrectArityForParameterizedConstructor);
            if (severity == ProblemSeverities.Ignore)
                return;
            if (noTypeVariables) {
                this.handle(IProblem.JavadocNonGenericConstructor, new String[] { new String(shownConstructor.declaringClass.sourceName()), typesAsString(shownConstructor, false), new String(shownConstructor.declaringClass.readableName()), typesAsString(targetConstructor, false) }, new String[] { new String(shownConstructor.declaringClass.sourceName()), typesAsString(shownConstructor, true), new String(shownConstructor.declaringClass.shortReadableName()), typesAsString(targetConstructor, true) }, severity, sourceStart, sourceEnd);
            } else {
                this.handle(IProblem.JavadocIncorrectArityForParameterizedConstructor, new String[] { new String(shownConstructor.declaringClass.sourceName()), typesAsString(shownConstructor, false), new String(shownConstructor.declaringClass.readableName()), typesAsString(shownConstructor.typeVariables, false), typesAsString(targetConstructor, false) }, new String[] { new String(shownConstructor.declaringClass.sourceName()), typesAsString(shownConstructor, true), new String(shownConstructor.declaringClass.shortReadableName()), typesAsString(shownConstructor.typeVariables, true), typesAsString(targetConstructor, true) }, severity, sourceStart, sourceEnd);
            }
            return;
        case ProblemReasons.ParameterizedMethodTypeMismatch:
            severity = computeSeverity(IProblem.JavadocParameterizedConstructorArgumentTypeMismatch);
            if (severity == ProblemSeverities.Ignore)
                return;
            problemConstructor = (ProblemMethodBinding) targetConstructor;
            shownConstructor = problemConstructor.closestMatch;
            this.handle(IProblem.JavadocParameterizedConstructorArgumentTypeMismatch, new String[] { new String(shownConstructor.declaringClass.sourceName()), typesAsString(shownConstructor, false), new String(shownConstructor.declaringClass.readableName()), typesAsString(((ParameterizedGenericMethodBinding) shownConstructor).typeArguments, false), typesAsString(targetConstructor, false) }, new String[] { new String(shownConstructor.declaringClass.sourceName()), typesAsString(shownConstructor, true), new String(shownConstructor.declaringClass.shortReadableName()), typesAsString(((ParameterizedGenericMethodBinding) shownConstructor).typeArguments, true), typesAsString(targetConstructor, true) }, severity, sourceStart, sourceEnd);
            return;
        case ProblemReasons.TypeArgumentsForRawGenericMethod:
            severity = computeSeverity(IProblem.JavadocTypeArgumentsForRawGenericConstructor);
            if (severity == ProblemSeverities.Ignore)
                return;
            problemConstructor = (ProblemMethodBinding) targetConstructor;
            shownConstructor = problemConstructor.closestMatch;
            this.handle(IProblem.JavadocTypeArgumentsForRawGenericConstructor, new String[] { new String(shownConstructor.declaringClass.sourceName()), typesAsString(shownConstructor, false), new String(shownConstructor.declaringClass.readableName()), typesAsString(targetConstructor, false) }, new String[] { new String(shownConstructor.declaringClass.sourceName()), typesAsString(shownConstructor, true), new String(shownConstructor.declaringClass.shortReadableName()), typesAsString(targetConstructor, true) }, severity, sourceStart, sourceEnd);
            return;
        // 0
        case ProblemReasons.NoError:
        default:
            // want to fail to see why we were here...
            needImplementation(statement);
            break;
    }
    int severity = computeSeverity(id);
    if (severity == ProblemSeverities.Ignore)
        return;
    this.handle(id, new String[] { new String(targetConstructor.declaringClass.readableName()), typesAsString(targetConstructor, false) }, new String[] { new String(targetConstructor.declaringClass.shortReadableName()), typesAsString(targetConstructor, true) }, severity, statement.sourceStart, statement.sourceEnd);
}
Also used : TypeVariableBinding(org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding) ProblemMethodBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding) AllocationExpression(org.eclipse.jdt.internal.compiler.ast.AllocationExpression) ArrayAllocationExpression(org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression) QualifiedAllocationExpression(org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression) TypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding) ParameterizedTypeBinding(org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding) SourceTypeBinding(org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding) ParameterizedGenericMethodBinding(org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding) MethodBinding(org.eclipse.jdt.internal.compiler.lookup.MethodBinding) ProblemMethodBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding) ParameterizedGenericMethodBinding(org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding)

Example 5 with ParameterizedGenericMethodBinding

use of org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding in project bazel-jdt-java-toolchain by salesforce.

the class MessageSend method resolveType.

@Override
public TypeBinding resolveType(BlockScope scope) {
    // Base type promotion
    if (this.constant != Constant.NotAConstant) {
        this.constant = Constant.NotAConstant;
        long sourceLevel = scope.compilerOptions().sourceLevel;
        boolean receiverCast = false;
        if (this.receiver instanceof CastExpression) {
            // will check later on
            this.receiver.bits |= ASTNode.DisableUnnecessaryCastCheck;
            receiverCast = true;
        }
        this.actualReceiverType = this.receiver.resolveType(scope);
        if (this.actualReceiverType instanceof InferenceVariable) {
            // not yet ready for resolving
            return null;
        }
        this.receiverIsType = this.receiver.isType();
        if (receiverCast && this.actualReceiverType != null) {
            // due to change of declaring class with receiver type, only identity cast should be notified
            TypeBinding resolvedType2 = ((CastExpression) this.receiver).expression.resolvedType;
            if (TypeBinding.equalsEquals(resolvedType2, this.actualReceiverType)) {
                if (!scope.environment().usesNullTypeAnnotations() || !NullAnnotationMatching.analyse(this.actualReceiverType, resolvedType2, -1).isAnyMismatch()) {
                    scope.problemReporter().unnecessaryCast((CastExpression) this.receiver);
                }
            }
        }
        // resolve type arguments (for generic constructor call)
        if (this.typeArguments != null) {
            int length = this.typeArguments.length;
            // typeChecks all arguments
            this.argumentsHaveErrors = sourceLevel < ClassFileConstants.JDK1_5;
            this.genericTypeArguments = new TypeBinding[length];
            for (int i = 0; i < length; i++) {
                TypeReference typeReference = this.typeArguments[i];
                if ((this.genericTypeArguments[i] = typeReference.resolveType(scope, true, /* check bounds*/
                Binding.DefaultLocationTypeArgument)) == null) {
                    this.argumentsHaveErrors = true;
                }
                if (this.argumentsHaveErrors && typeReference instanceof Wildcard) {
                    scope.problemReporter().illegalUsageOfWildcard(typeReference);
                }
            }
            if (this.argumentsHaveErrors) {
                if (this.arguments != null) {
                    // still attempt to resolve arguments
                    for (int i = 0, max = this.arguments.length; i < max; i++) {
                        this.arguments[i].resolveType(scope);
                    }
                }
                return null;
            }
        }
        // will check for null after args are resolved
        if (this.arguments != null) {
            // typeChecks all arguments
            this.argumentsHaveErrors = false;
            int length = this.arguments.length;
            this.argumentTypes = new TypeBinding[length];
            for (int i = 0; i < length; i++) {
                Expression argument = this.arguments[i];
                if (this.arguments[i].resolvedType != null)
                    // $NON-NLS-1$
                    scope.problemReporter().genericInferenceError("Argument was unexpectedly found resolved", this);
                if (argument instanceof CastExpression) {
                    // will check later on
                    argument.bits |= ASTNode.DisableUnnecessaryCastCheck;
                    this.argsContainCast = true;
                }
                argument.setExpressionContext(INVOCATION_CONTEXT);
                if ((this.argumentTypes[i] = argument.resolveType(scope)) == null) {
                    this.argumentsHaveErrors = true;
                }
            }
            if (this.argumentsHaveErrors) {
                if (this.actualReceiverType instanceof ReferenceBinding) {
                    // record a best guess, for clients who need hint about possible method match
                    TypeBinding[] pseudoArgs = new TypeBinding[length];
                    for (int i = length; --i >= 0; ) // replace args with errors with null type
                    pseudoArgs[i] = this.argumentTypes[i] == null ? TypeBinding.NULL : this.argumentTypes[i];
                    this.binding = this.receiver.isImplicitThis() ? scope.getImplicitMethod(this.selector, pseudoArgs, this) : scope.findMethod((ReferenceBinding) this.actualReceiverType, this.selector, pseudoArgs, this, false);
                    if (this.binding != null && !this.binding.isValidBinding()) {
                        MethodBinding closestMatch = ((ProblemMethodBinding) this.binding).closestMatch;
                        // record the closest match, for clients who may still need hint about possible method match
                        if (closestMatch != null) {
                            if (closestMatch.original().typeVariables != Binding.NO_TYPE_VARIABLES) {
                                // generic method
                                // shouldn't return generic method outside its context, rather convert it to raw method (175409)
                                closestMatch = scope.environment().createParameterizedGenericMethod(closestMatch.original(), (RawTypeBinding) null);
                            }
                            this.binding = closestMatch;
                            MethodBinding closestMatchOriginal = closestMatch.original();
                            if (closestMatchOriginal.isOrEnclosedByPrivateType() && !scope.isDefinedInMethod(closestMatchOriginal)) {
                                // ignore cases where method is used from within inside itself (e.g. direct recursions)
                                closestMatchOriginal.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
                            }
                        }
                    }
                }
                return null;
            }
        }
        if (this.actualReceiverType == null) {
            return null;
        }
        // base type cannot receive any message
        if (this.actualReceiverType.isBaseType()) {
            scope.problemReporter().errorNoMethodFor(this, this.actualReceiverType, this.argumentTypes);
            return null;
        }
    }
    TypeBinding methodType = findMethodBinding(scope);
    if (methodType != null && methodType.isPolyType()) {
        this.resolvedType = this.binding.returnType.capture(scope, this.sourceStart, this.sourceEnd);
        return methodType;
    }
    if (!this.binding.isValidBinding()) {
        if (this.binding.declaringClass == null) {
            if (this.actualReceiverType instanceof ReferenceBinding) {
                this.binding.declaringClass = (ReferenceBinding) this.actualReceiverType;
            } else {
                scope.problemReporter().errorNoMethodFor(this, this.actualReceiverType, this.argumentTypes);
                return null;
            }
        }
        // https://bugs.eclipse.org/bugs/show_bug.cgi?id=245007 avoid secondary errors in case of
        // missing super type for anonymous classes ...
        ReferenceBinding declaringClass = this.binding.declaringClass;
        boolean avoidSecondary = declaringClass != null && declaringClass.isAnonymousType() && declaringClass.superclass() instanceof MissingTypeBinding;
        if (!avoidSecondary)
            scope.problemReporter().invalidMethod(this, this.binding, scope);
        MethodBinding closestMatch = ((ProblemMethodBinding) this.binding).closestMatch;
        switch(this.binding.problemId()) {
            case ProblemReasons.Ambiguous:
                // no resilience on ambiguous
                break;
            case ProblemReasons.InferredApplicableMethodInapplicable:
            case ProblemReasons.InvocationTypeInferenceFailure:
                // Grabbing the closest match improves error reporting in nested invocation contexts
                if (this.expressionContext != INVOCATION_CONTEXT)
                    break;
            // $FALL-THROUGH$
            case ProblemReasons.NotVisible:
            case ProblemReasons.NonStaticReferenceInConstructorInvocation:
            case ProblemReasons.NonStaticReferenceInStaticContext:
            case ProblemReasons.ReceiverTypeNotVisible:
            case ProblemReasons.ParameterBoundMismatch:
                // only steal returnType in cases listed above
                if (closestMatch != null)
                    this.resolvedType = closestMatch.returnType;
                break;
            case ProblemReasons.ContradictoryNullAnnotations:
                if (closestMatch != null && closestMatch.returnType != null)
                    this.resolvedType = closestMatch.returnType.withoutToplevelNullAnnotation();
                break;
        }
        // record the closest match, for clients who may still need hint about possible method match
        if (closestMatch != null) {
            this.binding = closestMatch;
            MethodBinding closestMatchOriginal = closestMatch.original();
            if (closestMatchOriginal.isOrEnclosedByPrivateType() && !scope.isDefinedInMethod(closestMatchOriginal)) {
                // ignore cases where method is used from within inside itself (e.g. direct recursions)
                closestMatchOriginal.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
            }
        }
        return (this.resolvedType != null && (this.resolvedType.tagBits & TagBits.HasMissingType) == 0) ? this.resolvedType : null;
    }
    final CompilerOptions compilerOptions = scope.compilerOptions();
    if (compilerOptions.complianceLevel <= ClassFileConstants.JDK1_6 && this.binding.isPolymorphic()) {
        scope.problemReporter().polymorphicMethodNotBelow17(this);
        return null;
    }
    if (compilerOptions.isAnnotationBasedNullAnalysisEnabled) {
        ImplicitNullAnnotationVerifier.ensureNullnessIsKnown(this.binding, scope);
        if (compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8) {
            if (this.binding instanceof ParameterizedGenericMethodBinding && this.typeArguments != null) {
                TypeVariableBinding[] typeVariables = this.binding.original().typeVariables();
                for (int i = 0; i < this.typeArguments.length; i++) this.typeArguments[i].checkNullConstraints(scope, (ParameterizedGenericMethodBinding) this.binding, typeVariables, i);
            }
        }
    }
    if (this.binding.isPolymorphic()) {
        boolean resultDetermined = compilerOptions.sourceLevel >= ClassFileConstants.JDK9 && (this.binding.returnType == TypeBinding.VOID || this.binding.returnType.id != TypeIds.T_JavaLangObject);
        if (!resultDetermined && ((this.bits & ASTNode.InsideExpressionStatement) != 0)) {
            // we only set the return type to be void if this method invocation is used inside an expression statement
            this.binding = scope.environment().updatePolymorphicMethodReturnType((PolymorphicMethodBinding) this.binding, TypeBinding.VOID);
        }
    }
    if ((this.binding.tagBits & TagBits.HasMissingType) != 0) {
        scope.problemReporter().missingTypeInMethod(this, this.binding);
    }
    if (!this.binding.isStatic()) {
        // the "receiver" must not be a type
        if (this.receiverIsType) {
            scope.problemReporter().mustUseAStaticMethod(this, this.binding);
            if (this.actualReceiverType.isRawType() && (this.receiver.bits & ASTNode.IgnoreRawTypeCheck) == 0 && compilerOptions.getSeverity(CompilerOptions.RawTypeReference) != ProblemSeverities.Ignore) {
                scope.problemReporter().rawTypeReference(this.receiver, this.actualReceiverType);
            }
        } else {
            // handle indirect inheritance thru variable secondary bound
            // receiver may receive generic cast, as part of implicit conversion
            TypeBinding oldReceiverType = this.actualReceiverType;
            this.actualReceiverType = this.actualReceiverType.getErasureCompatibleType(this.binding.declaringClass);
            this.receiver.computeConversion(scope, this.actualReceiverType, this.actualReceiverType);
            if (TypeBinding.notEquals(this.actualReceiverType, oldReceiverType) && TypeBinding.notEquals(this.receiver.postConversionType(scope), this.actualReceiverType)) {
                // record need for explicit cast at codegen since receiver could not handle it
                this.bits |= NeedReceiverGenericCast;
            }
        }
    } else {
        // static message invoked through receiver? legal but unoptimal (optional warning).
        if (this.binding.declaringClass.isInterface() && !((isTypeAccess() || this.receiver.isImplicitThis()) && TypeBinding.equalsEquals(this.binding.declaringClass, this.actualReceiverType))) {
            scope.problemReporter().nonStaticOrAlienTypeReceiver(this, this.binding);
        } else if (!(this.receiver.isImplicitThis() || this.receiver.isSuper() || this.receiverIsType)) {
            scope.problemReporter().nonStaticAccessToStaticMethod(this, this.binding);
        }
        if (!this.receiver.isImplicitThis() && TypeBinding.notEquals(this.binding.declaringClass, this.actualReceiverType)) {
            scope.problemReporter().indirectAccessToStaticMethod(this, this.binding);
        }
    }
    if (checkInvocationArguments(scope, this.receiver, this.actualReceiverType, this.binding, this.arguments, this.argumentTypes, this.argsContainCast, this)) {
        this.bits |= ASTNode.Unchecked;
    }
    // -------message send that are known to fail at compile time-----------
    if (this.binding.isAbstract()) {
        if (this.receiver.isSuper()) {
            scope.problemReporter().cannotDireclyInvokeAbstractMethod(this, this.binding);
        }
    // abstract private methods cannot occur nor abstract static............
    }
    if (isMethodUseDeprecated(this.binding, scope, true, this))
        scope.problemReporter().deprecatedMethod(this.binding, this);
    TypeBinding returnType;
    if ((this.bits & ASTNode.Unchecked) != 0 && this.genericTypeArguments == null) {
        // https://bugs.eclipse.org/bugs/show_bug.cgi?id=277643, align with javac on JLS 15.12.2.6
        returnType = this.binding.returnType;
        if (returnType != null) {
            returnType = scope.environment().convertToRawType(returnType.erasure(), true);
        }
    } else {
        returnType = this.binding.returnType;
        if (returnType != null) {
            returnType = returnType.capture(scope, this.sourceStart, this.sourceEnd);
        }
    }
    this.resolvedType = returnType;
    if (this.receiver.isSuper() && compilerOptions.getSeverity(CompilerOptions.OverridingMethodWithoutSuperInvocation) != ProblemSeverities.Ignore) {
        final ReferenceContext referenceContext = scope.methodScope().referenceContext;
        if (referenceContext instanceof AbstractMethodDeclaration) {
            final AbstractMethodDeclaration abstractMethodDeclaration = (AbstractMethodDeclaration) referenceContext;
            MethodBinding enclosingMethodBinding = abstractMethodDeclaration.binding;
            if (enclosingMethodBinding.isOverriding() && CharOperation.equals(this.binding.selector, enclosingMethodBinding.selector) && this.binding.areParametersEqual(enclosingMethodBinding)) {
                abstractMethodDeclaration.bits |= ASTNode.OverridingMethodWithSupercall;
            }
        }
    }
    if (this.receiver.isSuper() && this.actualReceiverType.isInterface()) {
        // 15.12.3 (Java 8)
        scope.checkAppropriateMethodAgainstSupers(this.selector, this.binding, this.argumentTypes, this);
    }
    if (this.typeArguments != null && this.binding.original().typeVariables == Binding.NO_TYPE_VARIABLES) {
        scope.problemReporter().unnecessaryTypeArgumentsForMethodInvocation(this.binding, this.genericTypeArguments, this.typeArguments);
    }
    return (this.resolvedType.tagBits & TagBits.HasMissingType) == 0 ? this.resolvedType : null;
}
Also used : TypeVariableBinding(org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding) ProblemMethodBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding) SourceTypeBinding(org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding) TypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding) MissingTypeBinding(org.eclipse.jdt.internal.compiler.lookup.MissingTypeBinding) PolyTypeBinding(org.eclipse.jdt.internal.compiler.lookup.PolyTypeBinding) RawTypeBinding(org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding) PolymorphicMethodBinding(org.eclipse.jdt.internal.compiler.lookup.PolymorphicMethodBinding) PolyParameterizedGenericMethodBinding(org.eclipse.jdt.internal.compiler.lookup.PolyParameterizedGenericMethodBinding) ParameterizedGenericMethodBinding(org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding) ReferenceBinding(org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding) ProblemReferenceBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding) InferenceVariable(org.eclipse.jdt.internal.compiler.lookup.InferenceVariable) RawTypeBinding(org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding) MissingTypeBinding(org.eclipse.jdt.internal.compiler.lookup.MissingTypeBinding) CompilerOptions(org.eclipse.jdt.internal.compiler.impl.CompilerOptions) ReferenceContext(org.eclipse.jdt.internal.compiler.impl.ReferenceContext) PolymorphicMethodBinding(org.eclipse.jdt.internal.compiler.lookup.PolymorphicMethodBinding) ProblemMethodBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding) MethodBinding(org.eclipse.jdt.internal.compiler.lookup.MethodBinding) ParameterizedMethodBinding(org.eclipse.jdt.internal.compiler.lookup.ParameterizedMethodBinding) PolyParameterizedGenericMethodBinding(org.eclipse.jdt.internal.compiler.lookup.PolyParameterizedGenericMethodBinding) ParameterizedGenericMethodBinding(org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding)

Aggregations

ParameterizedGenericMethodBinding (org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding)9 MethodBinding (org.eclipse.jdt.internal.compiler.lookup.MethodBinding)8 ProblemMethodBinding (org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding)8 SourceTypeBinding (org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding)8 TypeBinding (org.eclipse.jdt.internal.compiler.lookup.TypeBinding)8 TypeVariableBinding (org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding)6 ParameterizedTypeBinding (org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding)5 ParameterizedMethodBinding (org.eclipse.jdt.internal.compiler.lookup.ParameterizedMethodBinding)3 ReferenceBinding (org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding)3 AllocationExpression (org.eclipse.jdt.internal.compiler.ast.AllocationExpression)2 ArrayAllocationExpression (org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression)2 QualifiedAllocationExpression (org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression)2 ProblemReferenceBinding (org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding)2 ConstructorDeclaration (org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration)1 ExplicitConstructorCall (org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall)1 CompilerOptions (org.eclipse.jdt.internal.compiler.impl.CompilerOptions)1 ReferenceContext (org.eclipse.jdt.internal.compiler.impl.ReferenceContext)1 ArrayBinding (org.eclipse.jdt.internal.compiler.lookup.ArrayBinding)1 InferenceContext18 (org.eclipse.jdt.internal.compiler.lookup.InferenceContext18)1 InferenceVariable (org.eclipse.jdt.internal.compiler.lookup.InferenceVariable)1