diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java index 48a41cbafc8f..0bfa3befdbc7 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java @@ -344,7 +344,23 @@ public class PsiSubstitutorImpl implements PsiSubstitutor { } } if (alreadyFound) continue;*/ - final PsiType substituted = substituteInternal(original); + PsiType substituted; + if (original instanceof PsiWildcardType) { + substituted = substituteInternal(original); + if (substituted instanceof PsiCapturedWildcardType) { + substituted = PsiCapturedWildcardType.create(((PsiCapturedWildcardType)substituted).getWildcard(), ((PsiCapturedWildcardType)substituted).getContext(), param); + } + else if (substituted instanceof PsiWildcardType) { + PsiType bound = ((PsiWildcardType)substituted).getBound(); + if (bound instanceof PsiCapturedWildcardType) { + bound = PsiCapturedWildcardType.create(((PsiCapturedWildcardType)bound).getWildcard(), ((PsiCapturedWildcardType)bound).getContext(), param); + substituted = ((PsiWildcardType)substituted).isExtends() ? PsiWildcardType.createExtends(((PsiWildcardType)substituted).getManager(), bound) + : PsiWildcardType.createSuper(((PsiWildcardType)substituted).getManager(), bound); + } + } + } else { + substituted = substituteInternal(original); + } //if (substituted == null) return false; substMap.put(param, substituted); } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/SubstituteTypeParameterOfCapturedWildcardOnSubstitution.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/SubstituteTypeParameterOfCapturedWildcardOnSubstitution.java new file mode 100644 index 000000000000..6bd8b7a192cf --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/SubstituteTypeParameterOfCapturedWildcardOnSubstitution.java @@ -0,0 +1,34 @@ +class B {} +abstract class A { + void baz5(B a) {} + abstract B foo5(); + void bar5(A a) { + baz5(a.foo5()); + } + + void baz7(B a) {} + abstract B foo7(); + void bar7(A a) { + baz7(a.foo7()); + } + + void baz9(B a) {} + abstract B foo9(); + void bar9(A a) { + baz9(a.foo9()); + } + + + void baz14(B a) {} + abstract B foo14(); + void bar14(A a) { + baz14(a.foo14()); + } + + + void baz24(B a) {} + abstract B foo24(); + void bar24(A a) { + baz24(a.foo24()); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java index 1e7629aefca6..bb377400bd06 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java @@ -446,6 +446,10 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } + public void testSubstituteTypeParameterOfCapturedWildcardOnSubstitution() throws Exception { + doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); + } + public void testJavaUtilCollections_NoVerify() throws Exception { PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule())); assertNotNull(collectionsClass);