Search in sources :

Example 1 with MethodCandidateInfo

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

the class HighlightMethodUtil method checkAmbiguousMethodCallIdentifier.

@Nullable
static HighlightInfo checkAmbiguousMethodCallIdentifier(@NotNull PsiReferenceExpression referenceToMethod, @NotNull JavaResolveResult[] resolveResults, @NotNull PsiExpressionList list, final PsiElement element, @NotNull JavaResolveResult resolveResult, @NotNull PsiMethodCallExpression methodCall, @NotNull PsiResolveHelper resolveHelper, @NotNull LanguageLevel languageLevel, @NotNull PsiFile file) {
    MethodCandidateInfo methodCandidate1 = null;
    MethodCandidateInfo methodCandidate2 = null;
    for (JavaResolveResult result : resolveResults) {
        if (!(result instanceof MethodCandidateInfo))
            continue;
        MethodCandidateInfo candidate = (MethodCandidateInfo) result;
        if (candidate.isApplicable() && !candidate.getElement().isConstructor()) {
            if (methodCandidate1 == null) {
                methodCandidate1 = candidate;
            } else {
                methodCandidate2 = candidate;
                break;
            }
        }
    }
    MethodCandidateInfo[] candidates = toMethodCandidates(resolveResults);
    HighlightInfoType highlightInfoType = HighlightInfoType.ERROR;
    if (methodCandidate2 != null) {
        return null;
    }
    String description;
    PsiElement elementToHighlight;
    if (element != null && !resolveResult.isAccessible()) {
        description = HighlightUtil.buildProblemWithAccessDescription(referenceToMethod, resolveResult);
        elementToHighlight = referenceToMethod.getReferenceNameElement();
    } else if (element != null && !resolveResult.isStaticsScopeCorrect()) {
        description = null;
        elementToHighlight = ObjectUtils.notNull(referenceToMethod.getReferenceNameElement(), referenceToMethod);
        if (element instanceof PsiMethod && ((PsiMethod) element).hasModifierProperty(PsiModifier.STATIC)) {
            PsiClass containingClass = ((PsiMethod) element).getContainingClass();
            if (containingClass != null && containingClass.isInterface()) {
                HighlightInfo info = HighlightUtil.checkFeature(elementToHighlight, HighlightUtil.Feature.STATIC_INTERFACE_CALLS, languageLevel, file);
                if (info != null)
                    return info;
                description = checkStaticInterfaceMethodCallQualifier(referenceToMethod, resolveResult.getCurrentFileResolveScope(), containingClass);
            }
        }
        if (description == null) {
            description = HighlightUtil.buildProblemWithStaticDescription(element);
        }
    } else {
        String methodName = referenceToMethod.getReferenceName() + buildArgTypesList(list);
        description = JavaErrorMessages.message("cannot.resolve.method", methodName);
        if (candidates.length == 0) {
            elementToHighlight = referenceToMethod.getReferenceNameElement();
            highlightInfoType = HighlightInfoType.WRONG_REF;
        } else {
            return null;
        }
    }
    String toolTip = XmlStringUtil.escapeString(description);
    HighlightInfo info = HighlightInfo.newHighlightInfo(highlightInfoType).range(elementToHighlight).description(description).escapedToolTip(toolTip).create();
    registerMethodCallIntentions(info, methodCall, list, resolveHelper);
    if (element != null && !resolveResult.isStaticsScopeCorrect()) {
        HighlightUtil.registerStaticProblemQuickFixAction(element, info, referenceToMethod);
    }
    TextRange fixRange = getFixRange(elementToHighlight);
    CastMethodArgumentFix.REGISTRAR.registerCastActions(candidates, methodCall, info, fixRange);
    WrapArrayToArraysAsListFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange);
    WrapLongWithMathToIntExactFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange);
    WrapObjectWithOptionalOfNullableFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange);
    WrapLongWithMathToIntExactFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange);
    PermuteArgumentsFix.registerFix(info, methodCall, candidates, fixRange);
    WrapExpressionFix.registerWrapAction(candidates, list.getExpressions(), info);
    registerChangeParameterClassFix(methodCall, list, info);
    return info;
}
Also used : MethodCandidateInfo(com.intellij.psi.infos.MethodCandidateInfo) HighlightInfo(com.intellij.codeInsight.daemon.impl.HighlightInfo) TextRange(com.intellij.openapi.util.TextRange) HighlightInfoType(com.intellij.codeInsight.daemon.impl.HighlightInfoType) Nullable(org.jetbrains.annotations.Nullable)

Example 2 with MethodCandidateInfo

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

the class HighlightMethodUtil method checkMethodCall.

@Nullable
static HighlightInfo checkMethodCall(@NotNull PsiMethodCallExpression methodCall, @NotNull PsiResolveHelper resolveHelper, @NotNull LanguageLevel languageLevel, @NotNull JavaSdkVersion javaSdkVersion, @NotNull PsiFile file) {
    PsiExpressionList list = methodCall.getArgumentList();
    PsiReferenceExpression referenceToMethod = methodCall.getMethodExpression();
    JavaResolveResult[] results = referenceToMethod.multiResolve(true);
    JavaResolveResult resolveResult = results.length == 1 ? results[0] : JavaResolveResult.EMPTY;
    PsiElement resolved = resolveResult.getElement();
    boolean isDummy = isDummyConstructorCall(methodCall, resolveHelper, list, referenceToMethod);
    if (isDummy)
        return null;
    HighlightInfo highlightInfo;
    final PsiSubstitutor substitutor = resolveResult.getSubstitutor();
    if (resolved instanceof PsiMethod && resolveResult.isValidResult()) {
        TextRange fixRange = getFixRange(methodCall);
        highlightInfo = HighlightUtil.checkUnhandledExceptions(methodCall, fixRange);
        if (highlightInfo == null && ((PsiMethod) resolved).hasModifierProperty(PsiModifier.STATIC)) {
            PsiClass containingClass = ((PsiMethod) resolved).getContainingClass();
            if (containingClass != null && containingClass.isInterface()) {
                PsiReferenceExpression methodRef = methodCall.getMethodExpression();
                PsiElement element = ObjectUtils.notNull(methodRef.getReferenceNameElement(), methodRef);
                highlightInfo = HighlightUtil.checkFeature(element, HighlightUtil.Feature.STATIC_INTERFACE_CALLS, languageLevel, file);
                if (highlightInfo == null) {
                    String message = checkStaticInterfaceMethodCallQualifier(methodRef, resolveResult.getCurrentFileResolveScope(), containingClass);
                    if (message != null) {
                        highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).descriptionAndTooltip(message).range(fixRange).create();
                    }
                }
            }
        }
        if (highlightInfo == null) {
            highlightInfo = GenericsHighlightUtil.checkInferredIntersections(substitutor, fixRange);
        }
        if (highlightInfo == null) {
            highlightInfo = checkVarargParameterErasureToBeAccessible((MethodCandidateInfo) resolveResult, methodCall);
        }
        if (highlightInfo == null) {
            String errorMessage = ((MethodCandidateInfo) resolveResult).getInferenceErrorMessage();
            if (errorMessage != null) {
                highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).descriptionAndTooltip(errorMessage).range(fixRange).create();
                if (highlightInfo != null) {
                    registerMethodCallIntentions(highlightInfo, methodCall, list, resolveHelper);
                    registerMethodReturnFixAction(highlightInfo, (MethodCandidateInfo) resolveResult, methodCall);
                }
            }
        }
    } else {
        PsiMethod resolvedMethod = null;
        MethodCandidateInfo candidateInfo = null;
        if (resolveResult instanceof MethodCandidateInfo) {
            candidateInfo = (MethodCandidateInfo) resolveResult;
            resolvedMethod = candidateInfo.getElement();
        }
        if (!resolveResult.isAccessible() || !resolveResult.isStaticsScopeCorrect()) {
            highlightInfo = null;
        } else if (candidateInfo != null && !candidateInfo.isApplicable()) {
            if (candidateInfo.isTypeArgumentsApplicable()) {
                String methodName = HighlightMessageUtil.getSymbolName(resolved, substitutor);
                PsiElement parent = resolved.getParent();
                String containerName = parent == null ? "" : HighlightMessageUtil.getSymbolName(parent, substitutor);
                String argTypes = buildArgTypesList(list);
                String description = JavaErrorMessages.message("wrong.method.arguments", methodName, containerName, argTypes);
                final Ref<PsiElement> elementToHighlight = new Ref<>(list);
                String toolTip;
                if (parent instanceof PsiClass) {
                    toolTip = buildOneLineMismatchDescription(list, candidateInfo, elementToHighlight);
                    if (toolTip == null) {
                        toolTip = createMismatchedArgumentsHtmlTooltip(candidateInfo, list);
                    }
                } else {
                    toolTip = description;
                }
                PsiElement element = elementToHighlight.get();
                // argument list starts with paren which there is no need to highlight
                int navigationShift = element instanceof PsiExpressionList ? +1 : 0;
                highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(element).description(description).escapedToolTip(toolTip).navigationShift(navigationShift).create();
                if (highlightInfo != null) {
                    registerMethodCallIntentions(highlightInfo, methodCall, list, resolveHelper);
                    registerMethodReturnFixAction(highlightInfo, candidateInfo, methodCall);
                }
            } else {
                PsiReferenceExpression methodExpression = methodCall.getMethodExpression();
                PsiReferenceParameterList typeArgumentList = methodCall.getTypeArgumentList();
                PsiSubstitutor applicabilitySubstitutor = candidateInfo.getSubstitutor(false);
                if (typeArgumentList.getTypeArguments().length == 0 && resolvedMethod.hasTypeParameters()) {
                    highlightInfo = GenericsHighlightUtil.checkInferredTypeArguments(resolvedMethod, methodCall, applicabilitySubstitutor);
                } else {
                    highlightInfo = GenericsHighlightUtil.checkParameterizedReferenceTypeArguments(resolved, methodExpression, applicabilitySubstitutor, javaSdkVersion);
                }
            }
        } else {
            String description = JavaErrorMessages.message("method.call.expected");
            highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(methodCall).descriptionAndTooltip(description).create();
            if (resolved instanceof PsiClass) {
                QuickFixAction.registerQuickFixAction(highlightInfo, QUICK_FIX_FACTORY.createInsertNewFix(methodCall, (PsiClass) resolved));
            } else {
                TextRange range = getFixRange(methodCall);
                QuickFixAction.registerQuickFixAction(highlightInfo, range, QUICK_FIX_FACTORY.createCreateMethodFromUsageFix(methodCall));
                QuickFixAction.registerQuickFixAction(highlightInfo, range, QUICK_FIX_FACTORY.createCreateAbstractMethodFromUsageFix(methodCall));
                QuickFixAction.registerQuickFixAction(highlightInfo, range, QUICK_FIX_FACTORY.createCreatePropertyFromUsageFix(methodCall));
                if (resolved instanceof PsiVariable && languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
                    PsiMethod method = LambdaUtil.getFunctionalInterfaceMethod(((PsiVariable) resolved).getType());
                    if (method != null) {
                        QuickFixAction.registerQuickFixAction(highlightInfo, range, QUICK_FIX_FACTORY.createInsertMethodCallFix(methodCall, method));
                    }
                }
            }
        }
    }
    if (highlightInfo == null) {
        highlightInfo = GenericsHighlightUtil.checkParameterizedReferenceTypeArguments(resolved, referenceToMethod, substitutor, javaSdkVersion);
    }
    return highlightInfo;
}
Also used : HighlightInfo(com.intellij.codeInsight.daemon.impl.HighlightInfo) TextRange(com.intellij.openapi.util.TextRange) Ref(com.intellij.openapi.util.Ref) MethodCandidateInfo(com.intellij.psi.infos.MethodCandidateInfo) Nullable(org.jetbrains.annotations.Nullable)

Example 3 with MethodCandidateInfo

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

the class HighlightMethodUtil method checkAmbiguousMethodCallArguments.

@Nullable
static HighlightInfo checkAmbiguousMethodCallArguments(@NotNull PsiReferenceExpression referenceToMethod, @NotNull JavaResolveResult[] resolveResults, @NotNull PsiExpressionList list, final PsiElement element, @NotNull JavaResolveResult resolveResult, @NotNull PsiMethodCallExpression methodCall, @NotNull PsiResolveHelper resolveHelper, @NotNull PsiElement elementToHighlight) {
    MethodCandidateInfo methodCandidate1 = null;
    MethodCandidateInfo methodCandidate2 = null;
    for (JavaResolveResult result : resolveResults) {
        if (!(result instanceof MethodCandidateInfo))
            continue;
        MethodCandidateInfo candidate = (MethodCandidateInfo) result;
        if (candidate.isApplicable() && !candidate.getElement().isConstructor()) {
            if (methodCandidate1 == null) {
                methodCandidate1 = candidate;
            } else {
                methodCandidate2 = candidate;
                break;
            }
        }
    }
    MethodCandidateInfo[] candidates = toMethodCandidates(resolveResults);
    String description;
    String toolTip;
    HighlightInfoType highlightInfoType = HighlightInfoType.ERROR;
    if (methodCandidate2 != null) {
        PsiMethod element1 = methodCandidate1.getElement();
        String m1 = PsiFormatUtil.formatMethod(element1, methodCandidate1.getSubstitutor(false), PsiFormatUtilBase.SHOW_CONTAINING_CLASS | PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_PARAMETERS, PsiFormatUtilBase.SHOW_TYPE);
        PsiMethod element2 = methodCandidate2.getElement();
        String m2 = PsiFormatUtil.formatMethod(element2, methodCandidate2.getSubstitutor(false), PsiFormatUtilBase.SHOW_CONTAINING_CLASS | PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_PARAMETERS, PsiFormatUtilBase.SHOW_TYPE);
        VirtualFile virtualFile1 = PsiUtilCore.getVirtualFile(element1);
        VirtualFile virtualFile2 = PsiUtilCore.getVirtualFile(element2);
        if (!Comparing.equal(virtualFile1, virtualFile2)) {
            if (virtualFile1 != null)
                m1 += " (In " + virtualFile1.getPresentableUrl() + ")";
            if (virtualFile2 != null)
                m2 += " (In " + virtualFile2.getPresentableUrl() + ")";
        }
        description = JavaErrorMessages.message("ambiguous.method.call", m1, m2);
        toolTip = createAmbiguousMethodHtmlTooltip(new MethodCandidateInfo[] { methodCandidate1, methodCandidate2 });
    } else {
        if (element != null && !resolveResult.isAccessible()) {
            return null;
        }
        if (element != null && !resolveResult.isStaticsScopeCorrect()) {
            return null;
        }
        String methodName = referenceToMethod.getReferenceName() + buildArgTypesList(list);
        description = JavaErrorMessages.message("cannot.resolve.method", methodName);
        if (candidates.length == 0) {
            return null;
        }
        toolTip = XmlStringUtil.escapeString(description);
    }
    HighlightInfo info = HighlightInfo.newHighlightInfo(highlightInfoType).range(elementToHighlight).description(description).escapedToolTip(toolTip).create();
    if (methodCandidate2 == null) {
        registerMethodCallIntentions(info, methodCall, list, resolveHelper);
    }
    if (!resolveResult.isAccessible() && resolveResult.isStaticsScopeCorrect() && methodCandidate2 != null) {
        HighlightUtil.registerAccessQuickFixAction((PsiMember) element, referenceToMethod, info, resolveResult.getCurrentFileResolveScope());
    }
    if (element != null && !resolveResult.isStaticsScopeCorrect()) {
        HighlightUtil.registerStaticProblemQuickFixAction(element, info, referenceToMethod);
    }
    TextRange fixRange = getFixRange(elementToHighlight);
    CastMethodArgumentFix.REGISTRAR.registerCastActions(candidates, methodCall, info, fixRange);
    WrapArrayToArraysAsListFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange);
    WrapLongWithMathToIntExactFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange);
    WrapObjectWithOptionalOfNullableFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange);
    WrapStringWithFileFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange);
    PermuteArgumentsFix.registerFix(info, methodCall, candidates, fixRange);
    WrapExpressionFix.registerWrapAction(candidates, list.getExpressions(), info);
    registerChangeParameterClassFix(methodCall, list, info);
    return info;
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) MethodCandidateInfo(com.intellij.psi.infos.MethodCandidateInfo) HighlightInfo(com.intellij.codeInsight.daemon.impl.HighlightInfo) TextRange(com.intellij.openapi.util.TextRange) HighlightInfoType(com.intellij.codeInsight.daemon.impl.HighlightInfoType) Nullable(org.jetbrains.annotations.Nullable)

Example 4 with MethodCandidateInfo

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

the class ParameterInfoTest method doTest2CandidatesWithPreselection.

private void doTest2CandidatesWithPreselection() {
    myFixture.configureByFile(getTestName(false) + ".java");
    MethodParameterInfoHandler handler = new MethodParameterInfoHandler();
    CreateParameterInfoContext context = new MockCreateParameterInfoContext(getEditor(), getFile());
    PsiExpressionList list = handler.findElementForParameterInfo(context);
    assertNotNull(list);
    Object[] itemsToShow = context.getItemsToShow();
    assertNotNull(itemsToShow);
    assertEquals(2, itemsToShow.length);
    assertTrue(itemsToShow[0] instanceof MethodCandidateInfo);
    ParameterInfoComponent.createContext(itemsToShow, getEditor(), handler, -1);
    MockUpdateParameterInfoContext updateParameterInfoContext = updateParameterInfo(handler, list, itemsToShow);
    assertTrue(updateParameterInfoContext.isUIComponentEnabled(0) || updateParameterInfoContext.isUIComponentEnabled(1));
}
Also used : MockUpdateParameterInfoContext(com.intellij.testFramework.utils.parameterInfo.MockUpdateParameterInfoContext) CreateParameterInfoContext(com.intellij.lang.parameterInfo.CreateParameterInfoContext) MockCreateParameterInfoContext(com.intellij.testFramework.utils.parameterInfo.MockCreateParameterInfoContext) MethodCandidateInfo(com.intellij.psi.infos.MethodCandidateInfo) MethodParameterInfoHandler(com.intellij.codeInsight.hint.api.impls.MethodParameterInfoHandler) MockCreateParameterInfoContext(com.intellij.testFramework.utils.parameterInfo.MockCreateParameterInfoContext)

Example 5 with MethodCandidateInfo

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

the class ChangeStringLiteralToCharInMethodCallFix method registerFixes.

public static void registerFixes(@NotNull final CandidateInfo[] candidates, @NotNull final PsiMethodCallExpression methodCall, @Nullable final HighlightInfo info) {
    if (info == null)
        return;
    final Set<PsiLiteralExpression> literals = new HashSet<>();
    boolean exactMatch = false;
    for (CandidateInfo candidate : candidates) {
        if (candidate instanceof MethodCandidateInfo) {
            final PsiMethod method = ((MethodCandidateInfo) candidate).getElement();
            exactMatch |= findMatchingExpressions(methodCall.getArgumentList().getExpressions(), method, literals);
        }
    }
    if (!exactMatch) {
        processLiterals(literals, methodCall, info);
    }
}
Also used : MethodCandidateInfo(com.intellij.psi.infos.MethodCandidateInfo) CandidateInfo(com.intellij.psi.infos.CandidateInfo) MethodCandidateInfo(com.intellij.psi.infos.MethodCandidateInfo) HashSet(java.util.HashSet)

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