Search in sources :

Example 16 with MethodCandidateInfo

use of com.intellij.psi.infos.MethodCandidateInfo in project intellij-community by JetBrains.

the class HighlightMethodUtil method checkConstructorCall.

static void checkConstructorCall(@NotNull PsiClassType.ClassResolveResult typeResolveResult, @NotNull PsiConstructorCall constructorCall, @NotNull PsiType type, PsiJavaCodeReferenceElement classReference, @NotNull HighlightInfoHolder holder, @NotNull JavaSdkVersion javaSdkVersion) {
    PsiExpressionList list = constructorCall.getArgumentList();
    if (list == null)
        return;
    PsiClass aClass = typeResolveResult.getElement();
    if (aClass == null)
        return;
    final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(holder.getProject()).getResolveHelper();
    PsiClass accessObjectClass = null;
    if (constructorCall instanceof PsiNewExpression) {
        PsiExpression qualifier = ((PsiNewExpression) constructorCall).getQualifier();
        if (qualifier != null) {
            accessObjectClass = (PsiClass) PsiUtil.getAccessObjectClass(qualifier).getElement();
        }
    }
    if (classReference != null && !resolveHelper.isAccessible(aClass, constructorCall, accessObjectClass)) {
        String description = HighlightUtil.buildProblemWithAccessDescription(classReference, typeResolveResult);
        PsiElement element = classReference.getReferenceNameElement();
        HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(element).descriptionAndTooltip(description).create();
        HighlightUtil.registerAccessQuickFixAction(aClass, classReference, info, null);
        holder.add(info);
        return;
    }
    PsiMethod[] constructors = aClass.getConstructors();
    if (constructors.length == 0) {
        if (list.getExpressions().length != 0) {
            String constructorName = aClass.getName();
            String argTypes = buildArgTypesList(list);
            String description = JavaErrorMessages.message("wrong.constructor.arguments", constructorName + "()", argTypes);
            String tooltip = createMismatchedArgumentsHtmlTooltip(list, null, PsiParameter.EMPTY_ARRAY, constructorName, PsiSubstitutor.EMPTY, aClass);
            HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(list).description(description).escapedToolTip(tooltip).navigationShift(+1).create();
            QuickFixAction.registerQuickFixAction(info, constructorCall.getTextRange(), QUICK_FIX_FACTORY.createCreateConstructorFromCallFix(constructorCall));
            if (classReference != null) {
                ConstructorParametersFixer.registerFixActions(classReference, constructorCall, info, getFixRange(list));
            }
            holder.add(info);
            return;
        }
        if (classReference != null && aClass.hasModifierProperty(PsiModifier.PROTECTED) && callingProtectedConstructorFromDerivedClass(constructorCall, aClass)) {
            holder.add(buildAccessProblem(classReference, typeResolveResult, aClass));
        } else if (aClass.isInterface() && constructorCall instanceof PsiNewExpression) {
            final PsiReferenceParameterList typeArgumentList = ((PsiNewExpression) constructorCall).getTypeArgumentList();
            if (typeArgumentList.getTypeArguments().length > 0) {
                holder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(typeArgumentList).descriptionAndTooltip("Anonymous class implements interface; cannot have type arguments").create());
            }
        }
    } else {
        PsiElement place = list;
        if (constructorCall instanceof PsiNewExpression) {
            final PsiAnonymousClass anonymousClass = ((PsiNewExpression) constructorCall).getAnonymousClass();
            if (anonymousClass != null)
                place = anonymousClass;
        }
        JavaResolveResult[] results = resolveHelper.multiResolveConstructor((PsiClassType) type, list, place);
        MethodCandidateInfo result = null;
        if (results.length == 1)
            result = (MethodCandidateInfo) results[0];
        PsiMethod constructor = result == null ? null : result.getElement();
        boolean applicable = true;
        try {
            final PsiDiamondType diamondType = constructorCall instanceof PsiNewExpression ? PsiDiamondType.getDiamondType((PsiNewExpression) constructorCall) : null;
            final JavaResolveResult staticFactory = diamondType != null ? diamondType.getStaticFactory() : null;
            applicable = staticFactory instanceof MethodCandidateInfo ? ((MethodCandidateInfo) staticFactory).isApplicable() : result != null && result.isApplicable();
        } catch (IndexNotReadyException e) {
        // ignore
        }
        PsiElement infoElement = list.getTextLength() > 0 ? list : constructorCall;
        if (constructor == null) {
            String name = aClass.getName();
            name += buildArgTypesList(list);
            String description = JavaErrorMessages.message("cannot.resolve.constructor", name);
            HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(list).descriptionAndTooltip(description).navigationShift(+1).create();
            if (info != null) {
                WrapExpressionFix.registerWrapAction(results, list.getExpressions(), info);
                registerFixesOnInvalidConstructorCall(constructorCall, classReference, list, aClass, constructors, results, infoElement, info);
                holder.add(info);
            }
        } else {
            if (classReference != null && (!result.isAccessible() || constructor.hasModifierProperty(PsiModifier.PROTECTED) && callingProtectedConstructorFromDerivedClass(constructorCall, aClass))) {
                holder.add(buildAccessProblem(classReference, result, constructor));
            } else if (!applicable) {
                String constructorName = HighlightMessageUtil.getSymbolName(constructor, result.getSubstitutor());
                String containerName = HighlightMessageUtil.getSymbolName(constructor.getContainingClass(), result.getSubstitutor());
                String argTypes = buildArgTypesList(list);
                String description = JavaErrorMessages.message("wrong.method.arguments", constructorName, containerName, argTypes);
                String toolTip = createMismatchedArgumentsHtmlTooltip(result, list);
                HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(infoElement).description(description).escapedToolTip(toolTip).navigationShift(+1).create();
                if (info != null) {
                    JavaResolveResult[] methodCandidates = results;
                    if (constructorCall instanceof PsiNewExpression) {
                        methodCandidates = resolveHelper.getReferencedMethodCandidates((PsiCallExpression) constructorCall, true);
                    }
                    registerFixesOnInvalidConstructorCall(constructorCall, classReference, list, aClass, constructors, methodCandidates, infoElement, info);
                    registerMethodReturnFixAction(info, result, constructorCall);
                    holder.add(info);
                }
            } else {
                if (constructorCall instanceof PsiNewExpression) {
                    PsiReferenceParameterList typeArgumentList = ((PsiNewExpression) constructorCall).getTypeArgumentList();
                    HighlightInfo info = GenericsHighlightUtil.checkReferenceTypeArgumentList(constructor, typeArgumentList, result.getSubstitutor(), false, javaSdkVersion);
                    if (info != null) {
                        holder.add(info);
                    }
                }
            }
        }
        if (result != null && !holder.hasErrorResults()) {
            holder.add(checkVarargParameterErasureToBeAccessible(result, constructorCall));
        }
    }
}
Also used : HighlightInfo(com.intellij.codeInsight.daemon.impl.HighlightInfo) MethodCandidateInfo(com.intellij.psi.infos.MethodCandidateInfo) IndexNotReadyException(com.intellij.openapi.project.IndexNotReadyException)

Example 17 with MethodCandidateInfo

use of com.intellij.psi.infos.MethodCandidateInfo in project intellij-community by JetBrains.

the class HighlightVisitorImpl method visitMethodReferenceExpression.

@Override
public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) {
    myHolder.add(checkFeature(expression, Feature.METHOD_REFERENCES));
    final PsiElement parent = PsiUtil.skipParenthesizedExprUp(expression.getParent());
    if (parent instanceof PsiExpressionStatement)
        return;
    final JavaResolveResult result;
    final JavaResolveResult[] results;
    try {
        results = expression.multiResolve(true);
        result = results.length == 1 ? results[0] : JavaResolveResult.EMPTY;
    } catch (IndexNotReadyException e) {
        return;
    }
    if (myRefCountHolder != null) {
        myRefCountHolder.registerReference(expression, result);
    }
    final PsiElement method = result.getElement();
    if (method != null && !result.isAccessible()) {
        final String accessProblem = HighlightUtil.buildProblemWithAccessDescription(expression, result);
        HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(accessProblem).create();
        HighlightUtil.registerAccessQuickFixAction((PsiMember) method, expression, info, result.getCurrentFileResolveScope());
        myHolder.add(info);
    } else {
        final TextAttributesScheme colorsScheme = myHolder.getColorsScheme();
        if (method instanceof PsiMethod && !expression.isConstructor()) {
            PsiElement methodNameElement = expression.getReferenceNameElement();
            if (methodNameElement != null) {
                myHolder.add(HighlightNamesUtil.highlightMethodName((PsiMethod) method, methodNameElement, false, colorsScheme));
            }
        }
        myHolder.add(HighlightNamesUtil.highlightClassNameInQualifier(expression, colorsScheme));
    }
    if (!LambdaUtil.isValidLambdaContext(parent)) {
        String description = "Method reference expression is not expected here";
        myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(description).create());
    }
    final PsiType functionalInterfaceType = expression.getFunctionalInterfaceType();
    if (!myHolder.hasErrorResults()) {
        if (functionalInterfaceType != null) {
            final boolean notFunctional = !LambdaUtil.isFunctionalType(functionalInterfaceType);
            if (notFunctional) {
                String description = functionalInterfaceType.getPresentableText() + " is not a functional interface";
                myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(description).create());
            }
        }
    }
    if (!myHolder.hasErrorResults()) {
        final PsiElement referenceNameElement = expression.getReferenceNameElement();
        if (referenceNameElement instanceof PsiKeyword) {
            if (!PsiMethodReferenceUtil.isValidQualifier(expression)) {
                PsiElement qualifier = expression.getQualifier();
                if (qualifier != null) {
                    String description = "Cannot find class " + qualifier.getText();
                    myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(qualifier).descriptionAndTooltip(description).create());
                }
            }
        }
    }
    if (!myHolder.hasErrorResults()) {
        checkFunctionalInterfaceTypeAccessible(expression, functionalInterfaceType);
    }
    if (!myHolder.hasErrorResults() && functionalInterfaceType != null) {
        final String errorMessage = PsiMethodReferenceUtil.checkMethodReferenceContext(expression);
        if (errorMessage != null) {
            final HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(errorMessage).create();
            if (method instanceof PsiMethod && !((PsiMethod) method).isConstructor() && !((PsiMethod) method).hasModifierProperty(PsiModifier.ABSTRACT)) {
                final boolean shouldHave = !((PsiMethod) method).hasModifierProperty(PsiModifier.STATIC);
                final LocalQuickFixAndIntentionActionOnPsiElement fixStaticModifier = QuickFixFactory.getInstance().createModifierListFix((PsiModifierListOwner) method, PsiModifier.STATIC, shouldHave, false);
                QuickFixAction.registerQuickFixAction(info, fixStaticModifier);
            }
            myHolder.add(info);
        }
    }
    if (!myHolder.hasErrorResults()) {
        PsiElement qualifier = expression.getQualifier();
        if (qualifier instanceof PsiTypeElement) {
            final PsiType psiType = ((PsiTypeElement) qualifier).getType();
            final HighlightInfo genericArrayCreationInfo = GenericsHighlightUtil.checkGenericArrayCreation(qualifier, psiType);
            if (genericArrayCreationInfo != null) {
                myHolder.add(genericArrayCreationInfo);
            } else {
                final String wildcardMessage = PsiMethodReferenceUtil.checkTypeArguments((PsiTypeElement) qualifier, psiType);
                if (wildcardMessage != null) {
                    myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(qualifier).descriptionAndTooltip(wildcardMessage).create());
                }
            }
        }
    }
    if (!myHolder.hasErrorResults()) {
        myHolder.add(PsiMethodReferenceHighlightingUtil.checkRawConstructorReference(expression));
    }
    if (!myHolder.hasErrorResults()) {
        myHolder.add(HighlightUtil.checkUnhandledExceptions(expression, expression.getTextRange()));
    }
    if (!myHolder.hasErrorResults()) {
        final String badReturnTypeMessage = PsiMethodReferenceUtil.checkReturnType(expression, result, functionalInterfaceType);
        if (badReturnTypeMessage != null) {
            myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(badReturnTypeMessage).create());
        }
    }
    if (!myHolder.hasErrorResults()) {
        if (results.length == 0 || results[0] instanceof MethodCandidateInfo && !((MethodCandidateInfo) results[0]).isApplicable() && functionalInterfaceType != null) {
            String description = null;
            if (results.length == 1) {
                description = ((MethodCandidateInfo) results[0]).getInferenceErrorMessage();
            }
            if (expression.isConstructor()) {
                final PsiClass containingClass = PsiMethodReferenceUtil.getQualifierResolveResult(expression).getContainingClass();
                if (containingClass != null) {
                    if (!myHolder.add(HighlightClassUtil.checkInstantiationOfAbstractClass(containingClass, expression)) && !myHolder.add(GenericsHighlightUtil.checkEnumInstantiation(expression, containingClass)) && containingClass.isPhysical() && description == null) {
                        description = JavaErrorMessages.message("cannot.resolve.constructor", containingClass.getName());
                    }
                }
            } else if (description == null) {
                description = JavaErrorMessages.message("cannot.resolve.method", expression.getReferenceName());
            }
            if (description != null) {
                final PsiElement referenceNameElement = expression.getReferenceNameElement();
                final HighlightInfo highlightInfo = HighlightInfo.newHighlightInfo(results.length == 0 ? HighlightInfoType.WRONG_REF : HighlightInfoType.ERROR).descriptionAndTooltip(description).range(referenceNameElement).create();
                myHolder.add(highlightInfo);
                final TextRange fixRange = HighlightMethodUtil.getFixRange(referenceNameElement);
                QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, QuickFixFactory.getInstance().createCreateMethodFromUsageFix(expression));
            }
        }
    }
}
Also used : TextAttributesScheme(com.intellij.openapi.editor.colors.TextAttributesScheme) TextRange(com.intellij.openapi.util.TextRange) LocalQuickFixAndIntentionActionOnPsiElement(com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement) MethodCandidateInfo(com.intellij.psi.infos.MethodCandidateInfo) IndexNotReadyException(com.intellij.openapi.project.IndexNotReadyException) LocalQuickFixAndIntentionActionOnPsiElement(com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement)

Example 18 with MethodCandidateInfo

use of com.intellij.psi.infos.MethodCandidateInfo in project intellij-community by JetBrains.

the class PermuteArgumentsFix method registerFix.

public static void registerFix(HighlightInfo info, PsiCall callExpression, final CandidateInfo[] candidates, final TextRange fixRange) {
    PsiExpression[] expressions = callExpression.getArgumentList().getExpressions();
    if (expressions.length < 2)
        return;
    List<PsiCall> permutations = new ArrayList<>();
    for (CandidateInfo candidate : candidates) {
        if (candidate instanceof MethodCandidateInfo) {
            MethodCandidateInfo methodCandidate = (MethodCandidateInfo) candidate;
            PsiMethod method = methodCandidate.getElement();
            PsiSubstitutor substitutor = methodCandidate.getSubstitutor();
            PsiParameter[] parameters = method.getParameterList().getParameters();
            if (expressions.length != parameters.length || parameters.length == 0)
                continue;
            int minIncompatibleIndex = parameters.length;
            int maxIncompatibleIndex = 0;
            int incompatibilitiesCount = 0;
            for (int i = 0; i < parameters.length; i++) {
                PsiParameter parameter = parameters[i];
                PsiType type = substitutor.substitute(parameter.getType());
                if (TypeConversionUtil.areTypesAssignmentCompatible(type, expressions[i]))
                    continue;
                if (minIncompatibleIndex == parameters.length)
                    minIncompatibleIndex = i;
                maxIncompatibleIndex = i;
                incompatibilitiesCount++;
            }
            try {
                registerSwapFixes(expressions, callExpression, permutations, methodCandidate, incompatibilitiesCount, minIncompatibleIndex, maxIncompatibleIndex);
                registerShiftFixes(expressions, callExpression, permutations, methodCandidate, minIncompatibleIndex, maxIncompatibleIndex);
            } catch (IncorrectOperationException e) {
                LOG.error(e);
            }
        }
    }
    if (permutations.size() == 1) {
        PermuteArgumentsFix fix = new PermuteArgumentsFix(callExpression, permutations.get(0));
        QuickFixAction.registerQuickFixAction(info, fixRange, fix);
    }
}
Also used : CandidateInfo(com.intellij.psi.infos.CandidateInfo) MethodCandidateInfo(com.intellij.psi.infos.MethodCandidateInfo) ArrayList(java.util.ArrayList) MethodCandidateInfo(com.intellij.psi.infos.MethodCandidateInfo) IncorrectOperationException(com.intellij.util.IncorrectOperationException)

Example 19 with MethodCandidateInfo

use of com.intellij.psi.infos.MethodCandidateInfo in project intellij-community by JetBrains.

the class Java8ExpressionsCheckTest method testRejectCachedTopLevelSessionIfItCorrespondsToTheWrongOverload.

public void testRejectCachedTopLevelSessionIfItCorrespondsToTheWrongOverload() throws Exception {
    final String filePath = BASE_PATH + "/" + getTestName(false) + ".java";
    configureByFile(filePath);
    PsiMethodCallExpression methodCall = PsiTreeUtil.getParentOfType(getFile().findElementAt(getEditor().getCaretModel().getOffset()), PsiMethodCallExpression.class);
    assertNotNull(methodCall);
    final PsiResolveHelper helper = JavaPsiFacade.getInstance(methodCall.getProject()).getResolveHelper();
    CandidateInfo[] candidates = helper.getReferencedMethodCandidates(methodCall, false, true);
    for (CandidateInfo candidate : candidates) {
        if (candidate instanceof MethodCandidateInfo) {
            //try to cache top level session
            candidate.getSubstitutor();
        }
    }
    doTestConfiguredFile(false, false, filePath);
}
Also used : MethodCandidateInfo(com.intellij.psi.infos.MethodCandidateInfo) CandidateInfo(com.intellij.psi.infos.CandidateInfo) MethodCandidateInfo(com.intellij.psi.infos.MethodCandidateInfo)

Example 20 with MethodCandidateInfo

use of com.intellij.psi.infos.MethodCandidateInfo in project intellij-community by JetBrains.

the class JavaMethodsConflictResolver method checkParametersNumber.

public boolean checkParametersNumber(@NotNull List<CandidateInfo> conflicts, final int argumentsCount, FactoryMap<MethodCandidateInfo, PsiSubstitutor> map, boolean ignoreIfStaticsProblem) {
    boolean atLeastOneMatch = false;
    TIntArrayList unmatchedIndices = null;
    for (int i = 0; i < conflicts.size(); i++) {
        ProgressManager.checkCanceled();
        CandidateInfo info = conflicts.get(i);
        if (ignoreIfStaticsProblem && !info.isStaticsScopeCorrect())
            return true;
        if (!(info instanceof MethodCandidateInfo))
            continue;
        PsiMethod method = ((MethodCandidateInfo) info).getElement();
        final int parametersCount = method.getParameterList().getParametersCount();
        boolean isVarargs = (myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8) ? ((MethodCandidateInfo) info).isVarargs() : method.isVarArgs()) && parametersCount - 1 <= argumentsCount;
        if (isVarargs || parametersCount == argumentsCount) {
            // remove all unmatched before
            if (unmatchedIndices != null) {
                for (int u = unmatchedIndices.size() - 1; u >= 0; u--) {
                    int index = unmatchedIndices.get(u);
                    //ensure super method with varargs won't win over non-vararg override
                    if (ignoreIfStaticsProblem && isVarargs) {
                        MethodCandidateInfo candidateInfo = (MethodCandidateInfo) conflicts.get(index);
                        PsiMethod candidateToRemove = candidateInfo.getElement();
                        if (candidateToRemove != method) {
                            PsiSubstitutor candidateToRemoveSubst = map.get(candidateInfo);
                            PsiSubstitutor substitutor = map.get(info);
                            if (MethodSignatureUtil.isSubsignature(candidateToRemove.getSignature(candidateToRemoveSubst), method.getSignature(substitutor))) {
                                continue;
                            }
                        }
                    }
                    conflicts.remove(index);
                    i--;
                }
                unmatchedIndices = null;
            }
            atLeastOneMatch = true;
        } else if (atLeastOneMatch) {
            conflicts.remove(i);
            i--;
        } else {
            if (unmatchedIndices == null)
                unmatchedIndices = new TIntArrayList(conflicts.size() - i);
            unmatchedIndices.add(i);
        }
    }
    return atLeastOneMatch;
}
Also used : MethodCandidateInfo(com.intellij.psi.infos.MethodCandidateInfo) CandidateInfo(com.intellij.psi.infos.CandidateInfo) MethodCandidateInfo(com.intellij.psi.infos.MethodCandidateInfo) TIntArrayList(gnu.trove.TIntArrayList)

Aggregations

MethodCandidateInfo (com.intellij.psi.infos.MethodCandidateInfo)27 CandidateInfo (com.intellij.psi.infos.CandidateInfo)12 HighlightInfo (com.intellij.codeInsight.daemon.impl.HighlightInfo)4 TextRange (com.intellij.openapi.util.TextRange)4 MethodParameterInfoHandler (com.intellij.codeInsight.hint.api.impls.MethodParameterInfoHandler)3 CreateParameterInfoContext (com.intellij.lang.parameterInfo.CreateParameterInfoContext)3 MockCreateParameterInfoContext (com.intellij.testFramework.utils.parameterInfo.MockCreateParameterInfoContext)3 Nullable (org.jetbrains.annotations.Nullable)3 HighlightInfoType (com.intellij.codeInsight.daemon.impl.HighlightInfoType)2 LocalQuickFixAndIntentionActionOnPsiElement (com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement)2 ParameterInfoUIContextEx (com.intellij.lang.parameterInfo.ParameterInfoUIContextEx)2 IndexNotReadyException (com.intellij.openapi.project.IndexNotReadyException)2 NotNull (org.jetbrains.annotations.NotNull)2 TextAttributesScheme (com.intellij.openapi.editor.colors.TextAttributesScheme)1 Pair (com.intellij.openapi.util.Pair)1 Ref (com.intellij.openapi.util.Ref)1 VirtualFile (com.intellij.openapi.vfs.VirtualFile)1 PsiElement (com.intellij.psi.PsiElement)1 JavaStubPsiElement (com.intellij.psi.impl.source.JavaStubPsiElement)1 ParameterTypeInferencePolicy (com.intellij.psi.impl.source.resolve.ParameterTypeInferencePolicy)1