new overload resolution

This commit is contained in:
anna
2013-11-06 12:40:26 +01:00
parent 971909ab56
commit 3546317c4d
3 changed files with 26 additions and 4 deletions
@@ -18,6 +18,7 @@ package com.intellij.psi;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.util.*;
import com.intellij.util.Function;
import com.sun.tools.javac.code.Kinds;
@@ -163,6 +164,10 @@ public class PsiMethodReferenceUtil {
public static boolean isAcceptable(@Nullable final PsiMethodReferenceExpression methodReferenceExpression, PsiType left) {
if (methodReferenceExpression == null) return false;
final PsiElement argsList = PsiTreeUtil.getParentOfType(methodReferenceExpression, PsiExpressionList.class);
if (MethodCandidateInfo.ourOverloadGuard.currentStack().contains(argsList)) {
if (!methodReferenceExpression.isExact()) return true;
}
if (left instanceof PsiIntersectionType) {
for (PsiType conjunct : ((PsiIntersectionType)left).getConjuncts()) {
if (isAcceptable(methodReferenceExpression, conjunct)) return true;
@@ -18,8 +18,10 @@ package com.intellij.psi.infos;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.JavaVersionService;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.RecursionGuard;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
@@ -37,6 +39,7 @@ import java.util.Map;
* @author ik, dsl
*/
public class MethodCandidateInfo extends CandidateInfo{
public static final RecursionGuard ourOverloadGuard = RecursionManager.createGuard("overload.guard");
public static final ThreadLocal<Map<PsiElement, Pair<PsiMethod, PsiSubstitutor>>> CURRENT_CANDIDATE = new ThreadLocal<Map<PsiElement, Pair<PsiMethod, PsiSubstitutor>>>();
@ApplicabilityLevelConstant private int myApplicabilityLevel = 0;
private final PsiElement myArgumentList;
@@ -95,6 +98,20 @@ public class MethodCandidateInfo extends CandidateInfo{
return myApplicabilityLevel;
}
@ApplicabilityLevelConstant
public int getPertinentApplicabilityLevel() {
final PsiMethod method = getElement();
if (method != null && method.hasTypeParameters() || myArgumentList == null || !PsiUtil.isLanguageLevel8OrHigher(myArgumentList)) {
return getApplicabilityLevel();
}
return ourOverloadGuard.doPreventingRecursion(myArgumentList, false, new Computable<Integer>() {
@Override
public Integer compute() {
return getApplicabilityLevelInner();
}
});
}
public PsiSubstitutor getSiteSubstitutor() {
return super.getSubstitutor();
}
@@ -394,7 +394,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
for (Iterator<CandidateInfo> iterator = conflicts.iterator(); iterator.hasNext();) {
ProgressManager.checkCanceled();
CandidateInfo info = iterator.next();
final int level = preferVarargs(info);
final int level = preferVarargs((MethodCandidateInfo)info);
if (level < maxApplicabilityLevel) {
iterator.remove();
}
@@ -404,10 +404,10 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
return maxApplicabilityLevel;
}
private static int preferVarargs(CandidateInfo info) {
final int level = ((MethodCandidateInfo)info).getApplicabilityLevel();
private static int preferVarargs(MethodCandidateInfo info) {
final int level = info.getPertinentApplicabilityLevel();
if (level == MethodCandidateInfo.ApplicabilityLevel.FIXED_ARITY) {
final PsiMethod psiMethod = (PsiMethod)info.getElement();
final PsiMethod psiMethod = info.getElement();
if (psiMethod != null && psiMethod.isVarArgs() && JavaVersionService.getInstance().isAtLeast(psiMethod, JavaSdkVersion.JDK_1_7)) {
return level + 1;
}