diff options
Diffstat (limited to 'java/java-psi-api/src/com/intellij')
3 files changed, 52 insertions, 10 deletions
diff --git a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java index 5ef2b8fe2ead..d8cdf4758148 100644 --- a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java @@ -270,16 +270,13 @@ public class GenericsUtil { continue; } final PsiType extendsBound = ((PsiWildcardType)substituted).getExtendsBound(); - if (Comparing.equal(TypeConversionUtil.erasure(extendsType), TypeConversionUtil.erasure(extendsBound))) { - if (extendsBound instanceof PsiClassType) { - if (acceptExtendsBound((PsiClassType)extendsBound, 0)) continue; - } else if (extendsBound instanceof PsiIntersectionType) { - for (PsiType psiType : ((PsiIntersectionType)extendsBound).getConjuncts()) { - if (psiType instanceof PsiClassType) { - if (acceptExtendsBound((PsiClassType)psiType, 0)) continue nextTypeParam; - } - } - } + if (acceptExtendsBound(extendsType, extendsBound)) { + continue nextTypeParam; + } + } + else if (substituted instanceof PsiIntersectionType) { + for (PsiType extendsBound : ((PsiIntersectionType)substituted).getConjuncts()) { + if (acceptExtendsBound(extendsType, extendsBound)) continue nextTypeParam; } } if (extendsType != null && !TypeConversionUtil.isAssignable(extendsType, substituted, allowUncheckedConversion)) { @@ -290,6 +287,22 @@ public class GenericsUtil { return null; } + public static boolean acceptExtendsBound(PsiType extendsType, PsiType extendsBound) { + if (Comparing.equal(TypeConversionUtil.erasure(extendsType), TypeConversionUtil.erasure(extendsBound))) { + if (extendsBound instanceof PsiClassType) { + if (acceptExtendsBound((PsiClassType)extendsBound, 0)) return true; + } + else if (extendsBound instanceof PsiIntersectionType) { + for (PsiType psiType : ((PsiIntersectionType)extendsBound).getConjuncts()) { + if (psiType instanceof PsiClassType) { + if (acceptExtendsBound((PsiClassType)psiType, 0)) return true; + } + } + } + } + return false; + } + private static boolean acceptExtendsBound(PsiClassType extendsBound, int depth) { PsiType[] parameters = extendsBound.getParameters(); if (parameters.length == 1) { @@ -303,6 +316,13 @@ public class GenericsUtil { if (bound instanceof PsiClassType && TypeConversionUtil.erasure(bound).equals(TypeConversionUtil.erasure(extendsBound))) { return acceptExtendsBound((PsiClassType)bound, depth + 1); } + if (bound instanceof PsiIntersectionType) { + for (PsiType extendsType : ((PsiIntersectionType)bound).getConjuncts()) { + if (acceptExtendsBound(extendsBound, extendsType)) { + return true; + } + } + } } } return false; diff --git a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java index 9bbb84e83020..f5f0bf96d95b 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java @@ -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; diff --git a/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java b/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java index 3a0bfddaf36f..8e4a13026514 100644 --- a/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java +++ b/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java @@ -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(); } |