diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java index e0e419b8a2dc..e9ed1cd85cb2 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java @@ -159,6 +159,15 @@ public class InferenceSession { return psiClass.getUserData(LOWER_BOUND); } + public static PsiType createTypeParameterTypeWithUpperBound(PsiType upperBound, PsiElement place) { + final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(place.getProject()); + + final PsiTypeParameter parameter = elementFactory.createTypeParameterFromText("T", place); + parameter.putUserData(UPPER_BOUND, upperBound); + + return elementFactory.createType(parameter); + } + public void initExpressionConstraints(PsiParameter[] parameters, PsiExpression[] args, PsiElement parent, PsiMethod method) { final MethodCandidateInfo.CurrentCandidateProperties currentProperties = getCurrentProperties(parent); initExpressionConstraints(parameters, args, parent, method, currentProperties != null && currentProperties.isVarargs()); diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java b/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java index 3bb13e38aafc..c7f71c000d2c 100644 --- a/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java @@ -23,6 +23,7 @@ import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.impl.PsiClassImplUtil; import com.intellij.psi.impl.source.resolve.JavaResolveUtil; +import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession; import com.intellij.psi.infos.ClassCandidateInfo; import com.intellij.psi.scope.JavaScopeProcessorEvent; import com.intellij.psi.scope.MethodProcessorSetupFailedException; @@ -128,9 +129,9 @@ public class PsiScopesUtil { processTypeDeclarations(lub, place, processor); } else if (type instanceof PsiCapturedWildcardType) { - final PsiType upperBound = getUpperBound((PsiCapturedWildcardType)type, place); - if (upperBound != null) { - processTypeDeclarations(PsiUtil.captureToplevelWildcards(upperBound, place), place, processor); + final PsiType classType = convertToTypeParameter((PsiCapturedWildcardType)type, place); + if (classType != null) { + processTypeDeclarations(classType, place, processor); } } else { @@ -142,15 +143,6 @@ public class PsiScopesUtil { } } - private static PsiType getUpperBound(PsiCapturedWildcardType type, PsiElement place) { - GlobalSearchScope placeResolveScope = place.getResolveScope(); - PsiType upperBound = PsiClassImplUtil.correctType(type.getUpperBound(), placeResolveScope); - while (upperBound instanceof PsiCapturedWildcardType) { - upperBound = PsiClassImplUtil.correctType(((PsiCapturedWildcardType)upperBound).getUpperBound(), placeResolveScope); - } - return upperBound; - } - public static boolean resolveAndWalk(@NotNull PsiScopeProcessor processor, @NotNull PsiJavaCodeReferenceElement ref, @Nullable PsiElement maxScope) { @@ -354,19 +346,13 @@ public class PsiScopesUtil { throw new MethodProcessorSetupFailedException("Cant determine qualifier type!"); } } - else if (type instanceof PsiIntersectionType) { - final PsiType[] conjuncts = ((PsiIntersectionType)type).getConjuncts(); - for (PsiType conjunct : conjuncts) { - if (!processQualifierType(conjunct, processor, manager, methodCall)) break; - } - } else if (type instanceof PsiDisjunctionType) { processQualifierType(((PsiDisjunctionType)type).getLeastUpperBound(), processor, manager, methodCall); } else if (type instanceof PsiCapturedWildcardType) { - final PsiType upperBound = getUpperBound((PsiCapturedWildcardType)type, methodCall); - if (upperBound != null) { - processQualifierType(PsiUtil.captureToplevelWildcards(upperBound, methodCall), processor, manager, methodCall); + final PsiType psiType = convertToTypeParameter((PsiCapturedWildcardType)type, methodCall); + if (psiType != null) { + processQualifierType(psiType, processor, manager, methodCall); } } else { @@ -406,6 +392,24 @@ public class PsiScopesUtil { } } + private static PsiType convertToTypeParameter(PsiCapturedWildcardType type, PsiElement methodCall) { + GlobalSearchScope placeResolveScope = methodCall.getResolveScope(); + PsiType upperBound = PsiClassImplUtil.correctType(type.getUpperBound(), placeResolveScope); + while (upperBound instanceof PsiCapturedWildcardType) { + upperBound = PsiClassImplUtil.correctType(((PsiCapturedWildcardType)upperBound).getUpperBound(), placeResolveScope); + } + + //arrays can't participate in extends list + if (upperBound instanceof PsiArrayType) { + return upperBound; + } + + if (upperBound != null) { + return InferenceSession.createTypeParameterTypeWithUpperBound(upperBound, methodCall); + } + return null; + } + private static boolean hasDesiredMethod(PsiMethodCallExpression methodCall, PsiType type, PsiAnonymousClass anonymousClass) { if (anonymousClass != null && type.equals(anonymousClass.getBaseClassType())) { final PsiMethod[] refMethods = anonymousClass.findMethodsByName(methodCall.getMethodExpression().getReferenceName(), false); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/MembersContainedInCapturedWildcardType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/MembersContainedInCapturedWildcardType.java new file mode 100644 index 000000000000..85daffd4463c --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/MembersContainedInCapturedWildcardType.java @@ -0,0 +1,13 @@ + +abstract class AbstractBean> { + + abstract B foo(); + abstract void bar(); + + private void bar1() {} + + private void getB(AbstractBean bean, B b) { + bean.foo().bar(); + bean.foo().bar1(); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java index 980e259b25f1..87398d77f925 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java @@ -1001,4 +1001,8 @@ public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase { public void testReifiableCapturedWildcards() throws Exception { doTest(true); } + + public void testMembersContainedInCapturedWildcardType() throws Exception { + doTest(); + } }