Search in sources :

Example 21 with MethodCandidateInfo

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

the class JavaMethodsConflictResolver method checkApplicability.

@MethodCandidateInfo.ApplicabilityLevelConstant
public int checkApplicability(@NotNull List<CandidateInfo> conflicts) {
    @MethodCandidateInfo.ApplicabilityLevelConstant int maxApplicabilityLevel = 0;
    boolean toFilter = false;
    for (CandidateInfo conflict : conflicts) {
        ProgressManager.checkCanceled();
        @MethodCandidateInfo.ApplicabilityLevelConstant final int level = getPertinentApplicabilityLevel((MethodCandidateInfo) conflict);
        if (maxApplicabilityLevel > 0 && maxApplicabilityLevel != level) {
            toFilter = true;
        }
        if (level > maxApplicabilityLevel) {
            maxApplicabilityLevel = level;
        }
    }
    if (toFilter) {
        for (Iterator<CandidateInfo> iterator = conflicts.iterator(); iterator.hasNext(); ) {
            ProgressManager.checkCanceled();
            CandidateInfo info = iterator.next();
            final int level = getPertinentApplicabilityLevel((MethodCandidateInfo) info);
            if (level < maxApplicabilityLevel) {
                iterator.remove();
            }
        }
    }
    return maxApplicabilityLevel;
}
Also used : CandidateInfo(com.intellij.psi.infos.CandidateInfo) MethodCandidateInfo(com.intellij.psi.infos.MethodCandidateInfo)

Example 22 with MethodCandidateInfo

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

the class JavaMethodsConflictResolver method checkStaticMethodsOfInterfaces.

/**
   * choose to accept static interface methods during search to get "Static interface methods must be invoked on containing interface class only" error
   * instead of non clear javac message that symbol not found
   * 
   * but these methods should be ignored during overload resolution if another methods are present
   */
private void checkStaticMethodsOfInterfaces(@NotNull List<CandidateInfo> conflicts) {
    if (!(myArgumentsList instanceof PsiExpressionList))
        return;
    PsiClass qualifierClass = null;
    for (Iterator<CandidateInfo> iterator = conflicts.iterator(); iterator.hasNext(); ) {
        CandidateInfo conflict = iterator.next();
        if (!(conflict instanceof MethodCandidateInfo))
            continue;
        final PsiMethod method = ((MethodCandidateInfo) conflict).getElement();
        if (method.hasModifierProperty(PsiModifier.STATIC)) {
            if (conflict.getCurrentFileResolveScope() instanceof PsiImportStaticStatement)
                continue;
            final PsiClass containingClass = method.getContainingClass();
            if (containingClass != null && containingClass.isInterface()) {
                if (qualifierClass == null) {
                    qualifierClass = getQualifiedClass(method);
                    if (qualifierClass == null)
                        return;
                }
                if (!containingClass.getManager().areElementsEquivalent(containingClass, qualifierClass)) {
                    iterator.remove();
                }
            }
        }
    }
}
Also used : MethodCandidateInfo(com.intellij.psi.infos.MethodCandidateInfo) CandidateInfo(com.intellij.psi.infos.CandidateInfo) MethodCandidateInfo(com.intellij.psi.infos.MethodCandidateInfo)

Example 23 with MethodCandidateInfo

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

the class DuplicateConflictResolver method resolveConflict.

@Override
public CandidateInfo resolveConflict(@NotNull List<CandidateInfo> conflicts) {
    if (conflicts.size() == 1)
        return conflicts.get(0);
    final Map<Object, CandidateInfo> uniqueItems = new HashMap<>();
    for (CandidateInfo info : conflicts) {
        final PsiElement element = info.getElement();
        Object key;
        if (info instanceof MethodCandidateInfo) {
            key = ((PsiMethod) element).getSignature(((MethodCandidateInfo) info).getSubstitutor(false));
        } else {
            key = PsiUtilCore.getName(element);
        }
        if (!uniqueItems.containsKey(key)) {
            uniqueItems.put(key, info);
        }
    }
    if (uniqueItems.size() == 1)
        return uniqueItems.values().iterator().next();
    return null;
}
Also used : HashMap(com.intellij.util.containers.HashMap) MethodCandidateInfo(com.intellij.psi.infos.MethodCandidateInfo) CandidateInfo(com.intellij.psi.infos.CandidateInfo) MethodCandidateInfo(com.intellij.psi.infos.MethodCandidateInfo) PsiElement(com.intellij.psi.PsiElement)

Example 24 with MethodCandidateInfo

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

the class MethodReferenceResolver method resolve.

@NotNull
@Override
public JavaResolveResult[] resolve(@NotNull final PsiMethodReferenceExpressionImpl reference, @NotNull final PsiFile containingFile, boolean incompleteCode) {
    final PsiMethodReferenceUtil.QualifierResolveResult qualifierResolveResult = PsiMethodReferenceUtil.getQualifierResolveResult(reference);
    final PsiClass containingClass = qualifierResolveResult.getContainingClass();
    PsiSubstitutor substitutor = qualifierResolveResult.getSubstitutor();
    if (containingClass != null) {
        final PsiElement element = reference.getReferenceNameElement();
        final boolean isConstructor = reference.isConstructor();
        if (element instanceof PsiIdentifier || isConstructor) {
            if (isConstructor && !canBeConstructed(containingClass)) {
                return JavaResolveResult.EMPTY_ARRAY;
            }
            final PsiType functionalInterfaceType = getInterfaceType(reference);
            final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
            final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
            final PsiSubstitutor functionalInterfaceSubstitutor = interfaceMethod != null ? LambdaUtil.getSubstitutor(interfaceMethod, resolveResult) : null;
            final MethodSignature signature = interfaceMethod != null ? interfaceMethod.getSignature(functionalInterfaceSubstitutor) : null;
            final PsiType interfaceMethodReturnType = LambdaUtil.getFunctionalInterfaceReturnType(functionalInterfaceType);
            if (isConstructor && containingClass.getConstructors().length == 0) {
                if (interfaceMethod != null) {
                    final PsiClassType returnType = composeReturnType(containingClass, substitutor);
                    final InferenceSession session = new InferenceSession(containingClass.getTypeParameters(), substitutor, reference.getManager(), null);
                    if (!(session.isProperType(session.substituteWithInferenceVariables(returnType)) && session.isProperType(interfaceMethodReturnType))) {
                        session.registerReturnTypeConstraints(returnType, interfaceMethodReturnType);
                        substitutor = session.infer();
                    }
                }
                ClassCandidateInfo candidateInfo = null;
                final boolean isArray = PsiEquivalenceUtil.areElementsEquivalent(containingClass, JavaPsiFacade.getElementFactory(reference.getProject()).getArrayClass(PsiUtil.getLanguageLevel(reference)));
                if (signature == null || !isArray && (containingClass.getContainingClass() == null || !isLocatedInStaticContext(containingClass, reference)) && signature.getParameterTypes().length == 0 || isArray && arrayCreationSignature(signature)) {
                    candidateInfo = new ClassCandidateInfo(containingClass, substitutor);
                }
                return candidateInfo == null ? JavaResolveResult.EMPTY_ARRAY : new JavaResolveResult[] { candidateInfo };
            }
            final PsiConflictResolver conflictResolver = createResolver(reference, qualifierResolveResult, interfaceMethod, signature);
            final MethodCandidatesProcessor processor = new MethodCandidatesProcessor(reference, containingFile, new PsiConflictResolver[] { conflictResolver }, new SmartList<>()) {

                @Override
                protected boolean acceptVarargs() {
                    return true;
                }

                @Override
                protected MethodCandidateInfo createCandidateInfo(@NotNull final PsiMethod method, @NotNull final PsiSubstitutor substitutor, final boolean staticProblem, final boolean accessible, final boolean varargs) {
                    final PsiExpressionList argumentList = getArgumentList();
                    final PsiType[] typeParameters = reference.getTypeParameters();
                    return new MethodCandidateInfo(method, substitutor, !accessible, staticProblem, argumentList, myCurrentFileContext, argumentList != null ? argumentList.getExpressionTypes() : null, method.hasTypeParameters() && typeParameters.length > 0 ? typeParameters : null, getLanguageLevel()) {

                        @Override
                        public boolean isVarargs() {
                            return varargs;
                        }

                        @NotNull
                        @Override
                        public PsiSubstitutor inferTypeArguments(@NotNull ParameterTypeInferencePolicy policy, boolean includeReturnConstraint) {
                            return inferTypeArguments(includeReturnConstraint);
                        }

                        private PsiSubstitutor inferTypeArguments(boolean includeReturnConstraint) {
                            if (interfaceMethod == null)
                                return substitutor;
                            final InferenceSession session = new InferenceSession(method.getTypeParameters(), substitutor, reference.getManager(), reference);
                            session.initThrowsConstraints(method);
                            final PsiSubstitutor psiSubstitutor = session.collectApplicabilityConstraints(reference, this, functionalInterfaceType);
                            if (psiSubstitutor != null) {
                                return psiSubstitutor;
                            }
                            if (!session.repeatInferencePhases()) {
                                return substitutor;
                            }
                            if (includeReturnConstraint && !PsiType.VOID.equals(interfaceMethodReturnType) && interfaceMethodReturnType != null) {
                                PsiSubstitutor subst = PsiMethodReferenceCompatibilityConstraint.getSubstitutor(signature, qualifierResolveResult, method, containingClass, reference);
                                final PsiType returnType = method.isConstructor() ? composeReturnType(containingClass, subst) : subst.substitute(method.getReturnType());
                                if (returnType != null) {
                                    session.registerReturnTypeConstraints(returnType, interfaceMethodReturnType);
                                }
                            }
                            return session.infer(method.getParameterList().getParameters(), null, null);
                        }

                        @Override
                        public boolean isApplicable() {
                            if (signature == null)
                                return false;
                            final PsiType[] argTypes = signature.getParameterTypes();
                            boolean hasReceiver = PsiMethodReferenceUtil.isSecondSearchPossible(argTypes, qualifierResolveResult, reference);
                            return MethodReferenceConflictResolver.isApplicableByFirstSearch(this, argTypes, hasReceiver, reference, interfaceMethod.isVarArgs()) != null;
                        }
                    };
                }
            };
            processor.setIsConstructor(isConstructor);
            processor.setName(isConstructor ? containingClass.getName() : element.getText());
            final PsiExpression expression = reference.getQualifierExpression();
            if (expression == null || !(expression.getType() instanceof PsiArrayType)) {
                processor.setAccessClass(containingClass);
            }
            if (qualifierResolveResult.isReferenceTypeQualified() && isLocatedInStaticContext(containingClass, reference)) {
                processor.handleEvent(JavaScopeProcessorEvent.START_STATIC, null);
            }
            ResolveState state = ResolveState.initial().put(PsiSubstitutor.KEY, substitutor);
            containingClass.processDeclarations(processor, state, reference, reference);
            return processor.getResult();
        }
    }
    return JavaResolveResult.EMPTY_ARRAY;
}
Also used : NotNull(org.jetbrains.annotations.NotNull) PsiConflictResolver(com.intellij.psi.scope.PsiConflictResolver) MethodCandidateInfo(com.intellij.psi.infos.MethodCandidateInfo) ClassCandidateInfo(com.intellij.psi.infos.ClassCandidateInfo) MethodCandidatesProcessor(com.intellij.psi.scope.processor.MethodCandidatesProcessor) MethodSignature(com.intellij.psi.util.MethodSignature) InferenceSession(com.intellij.psi.impl.source.resolve.graphInference.InferenceSession) ParameterTypeInferencePolicy(com.intellij.psi.impl.source.resolve.ParameterTypeInferencePolicy) NotNull(org.jetbrains.annotations.NotNull)

Example 25 with MethodCandidateInfo

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

the class ResolveMethod15Test method testStaticImportDirect.

public void testStaticImportDirect() throws Exception {
    final PsiReference ref = configureByFile();
    final PsiElement element = ref.resolve();
    assertNotNull(element);
    assertThat(element, instanceOf(PsiMethod.class));
    final PsiMethod method = (PsiMethod) element;
    assertEquals("asList", method.getName());
    assertEquals("java.util.Arrays", method.getContainingClass().getQualifiedName());
    assertThat(ref, instanceOf(PsiReferenceExpression.class));
    final PsiReferenceExpression refExpr = (PsiReferenceExpression) ref;
    final JavaResolveResult[] resolveResults = refExpr.multiResolve(false);
    assertEquals(1, resolveResults.length);
    final JavaResolveResult resolveResult = resolveResults[0];
    assertTrue(resolveResult.isValidResult());
    assertThat(resolveResult.getCurrentFileResolveScope(), instanceOf(PsiImportStaticStatement.class));
    assertThat(resolveResult, instanceOf(MethodCandidateInfo.class));
    final MethodCandidateInfo methodCandidateInfo = (MethodCandidateInfo) resolveResult;
    assertTrue(methodCandidateInfo.isApplicable());
}
Also used : MethodCandidateInfo(com.intellij.psi.infos.MethodCandidateInfo)

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