summaryrefslogtreecommitdiff
path: root/java/java-psi-api/src/com/intellij
diff options
context:
space:
mode:
Diffstat (limited to 'java/java-psi-api/src/com/intellij')
-rw-r--r--java/java-psi-api/src/com/intellij/psi/GenericsUtil.java40
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java5
-rw-r--r--java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java17
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();
}