Search in sources :

Example 41 with CandidateInfo

use of com.intellij.psi.infos.CandidateInfo 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)

Example 42 with CandidateInfo

use of com.intellij.psi.infos.CandidateInfo 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 43 with CandidateInfo

use of com.intellij.psi.infos.CandidateInfo 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 44 with CandidateInfo

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

the class JavaVariableConflictResolver method resolveConflict.

@Override
public CandidateInfo resolveConflict(@NotNull List<CandidateInfo> conflicts) {
    final int size = conflicts.size();
    if (size == 1) {
        return conflicts.get(0);
    }
    if (size == 0) {
        return null;
    }
    final CandidateInfo[] uncheckedResult = conflicts.toArray(new CandidateInfo[size]);
    CandidateInfo currentResult = uncheckedResult[0];
    PsiElement currentElement = currentResult.getElement();
    if (currentElement instanceof PsiField) {
        for (int i = 1; i < uncheckedResult.length; i++) {
            final CandidateInfo candidate = uncheckedResult[i];
            final PsiElement otherElement = candidate.getElement();
            if (!(otherElement instanceof PsiField)) {
                if (otherElement instanceof PsiLocalVariable) {
                    return candidate;
                } else {
                    if (!currentResult.isAccessible())
                        return candidate;
                    conflicts.remove(candidate);
                    continue;
                }
            }
            final PsiClass newClass = ((PsiField) otherElement).getContainingClass();
            final PsiClass oldClass = ((PsiField) currentElement).getContainingClass();
            final PsiElement scope = currentResult.getCurrentFileResolveScope();
            Boolean oldClassIsInheritor = null;
            if (newClass != null && oldClass != null) {
                if (newClass.isInheritor(oldClass, true)) {
                    if (scope instanceof PsiClass && (scope.equals(oldClass) || scope.equals(newClass) || !((PsiClass) scope).isInheritorDeep(oldClass, newClass))) {
                        // candidate is better
                        conflicts.remove(currentResult);
                        currentResult = candidate;
                        currentElement = currentResult.getElement();
                        continue;
                    }
                } else if (oldClassIsInheritor = oldClass.isInheritor(newClass, true)) {
                    if (!(scope instanceof PsiClass) || scope.equals(oldClass) || scope.equals(newClass) || !((PsiClass) scope).isInheritorDeep(newClass, oldClass)) {
                        // candidate is worse
                        conflicts.remove(candidate);
                        continue;
                    }
                }
            }
            if (!candidate.isAccessible()) {
                conflicts.remove(candidate);
                continue;
            }
            if (!currentResult.isAccessible()) {
                conflicts.remove(currentResult);
                currentResult = candidate;
                currentElement = currentResult.getElement();
                continue;
            }
            //This test should go last
            if (otherElement == currentElement) {
                conflicts.remove(candidate);
                continue;
            }
            if (oldClassIsInheritor == null) {
                oldClassIsInheritor = oldClass != null && newClass != null && oldClass.isInheritor(newClass, true);
            }
            if (oldClassIsInheritor) {
                // both fields are accessible
                // field in derived hides field in base
                conflicts.remove(candidate);
                continue;
            }
            return null;
        }
    }
    return currentResult;
}
Also used : CandidateInfo(com.intellij.psi.infos.CandidateInfo) PsiField(com.intellij.psi.PsiField) PsiClass(com.intellij.psi.PsiClass) PsiLocalVariable(com.intellij.psi.PsiLocalVariable) PsiElement(com.intellij.psi.PsiElement)

Example 45 with CandidateInfo

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

the class ConflictFilterProcessor method getResult.

@NotNull
public JavaResolveResult[] getResult() {
    JavaResolveResult[] cachedResult = myCachedResult;
    if (cachedResult == null) {
        List<CandidateInfo> conflicts = getResults();
        if (!conflicts.isEmpty()) {
            for (PsiConflictResolver resolver : myResolvers) {
                CandidateInfo candidate = resolver.resolveConflict(conflicts);
                if (candidate != null) {
                    conflicts.clear();
                    conflicts.add(candidate);
                    break;
                }
            }
        }
        myCachedResult = cachedResult = conflicts.toArray(new JavaResolveResult[conflicts.size()]);
    }
    return cachedResult;
}
Also used : PsiConflictResolver(com.intellij.psi.scope.PsiConflictResolver) CandidateInfo(com.intellij.psi.infos.CandidateInfo) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

CandidateInfo (com.intellij.psi.infos.CandidateInfo)60 MethodCandidateInfo (com.intellij.psi.infos.MethodCandidateInfo)19 NotNull (org.jetbrains.annotations.NotNull)13 Nullable (org.jetbrains.annotations.Nullable)6 Pair (com.intellij.openapi.util.Pair)4 ArrayList (java.util.ArrayList)4 HashSet (java.util.HashSet)4 GrModifierList (org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList)4 Project (com.intellij.openapi.project.Project)3 TextRange (com.intellij.openapi.util.TextRange)3 PsiClass (com.intellij.psi.PsiClass)3 PsiElement (com.intellij.psi.PsiElement)3 IncorrectOperationException (com.intellij.util.IncorrectOperationException)3 GrReferenceList (org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrReferenceList)3 PsiMethodMember (com.intellij.codeInsight.generation.PsiMethodMember)2 Result (com.intellij.openapi.application.Result)2 WriteCommandAction (com.intellij.openapi.command.WriteCommandAction)2 LanguageLevel (com.intellij.pom.java.LanguageLevel)2 ClassCandidateInfo (com.intellij.psi.infos.ClassCandidateInfo)2 PsiScopeProcessor (com.intellij.psi.scope.PsiScopeProcessor)2