From 7c3f532d9c5c33e445c92020e2b2d57bfb9f9ed0 Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 2 May 2012 16:48:49 +0200 Subject: [PATCH] do not create another capture when not necessary; capture should be the same when substitutor define such dependency (IDEA-57340; IDEA-5731) --- .../intellij/psi/impl/PsiSubstitutorImpl.java | 12 ++++++++- .../source/resolve/PsiResolveHelperImpl.java | 13 ++++++++++ .../genericsHighlighting/IDEA57340.java | 26 +++++++++++++++++++ .../daemon/GenericsHighlightingTest.java | 1 + 4 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA57340.java 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 feb757c54883..c3cfe4b23c47 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 @@ -283,6 +283,14 @@ public class PsiSubstitutorImpl implements PsiSubstitutor { if (original == null) { substMap.put(param, null); } else { + /*boolean alreadyFound = false; + for (Map.Entry entry : substMap.entrySet()) { + if (original.equals(originalSubstitutor.substitute(entry.getKey()))) { + substMap.put(param, entry.getValue()); + alreadyFound = true; + } + } + if (alreadyFound) continue;*/ final PsiType substituted = substituteInternal(original); if (substituted == null) return false; substMap.put(param, substituted); @@ -297,6 +305,7 @@ public class PsiSubstitutorImpl implements PsiSubstitutor { } private PsiType addBounds(PsiType substituted, final PsiTypeParameter typeParameter) { + PsiType oldSubstituted = substituted; PsiElement captureContext = null; if (substituted instanceof PsiCapturedWildcardType) { final PsiCapturedWildcardType captured = (PsiCapturedWildcardType)substituted; @@ -331,7 +340,8 @@ public class PsiSubstitutorImpl implements PsiSubstitutor { if (captureContext != null) { LOG.assertTrue(substituted instanceof PsiWildcardType); - substituted = PsiCapturedWildcardType.create((PsiWildcardType)substituted, captureContext); + substituted = oldSubstituted instanceof PsiCapturedWildcardType && substituted == ((PsiCapturedWildcardType)oldSubstituted).getWildcard() + ? oldSubstituted : PsiCapturedWildcardType.create((PsiWildcardType)substituted, captureContext); } return substituted; } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java index 323dca8aeba9..4574629d0aa4 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java @@ -606,6 +606,19 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { PsiType paramType = paramResult.getSubstitutor().substitute(typeParameter); PsiType argType = argResult.getSubstitutor().substituteWithBoundsPromotion(typeParameter); + if (wildcardCaptured != null) { + boolean alreadyFound = false; + for (PsiTypeParameter typeParam : PsiUtil.typeParametersIterable(paramClass)) { + if (typeParam != typeParameter && + paramType != null && + argResult.getSubstitutor().substituteWithBoundsPromotion(typeParam) == argType && + paramType.equals(paramResult.getSubstitutor().substitute(typeParam))) { + alreadyFound = true; + } + } + if (alreadyFound) continue; + } + Pair res = getSubstitutionForTypeParameterInner(paramType, argType, patternType, ConstraintType.EQUALS, depth + 1); if (res != null) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA57340.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA57340.java new file mode 100644 index 000000000000..7bbba7bc65fc --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA57340.java @@ -0,0 +1,26 @@ +class A { +} + +class B { + A foo() { + return null; + } + + void bar(B b, A foo1) { + baz(b.foo()); + A foo = b.foo(); + baz(foo); + baz(foo1); + } + + void baz(A a) { + } +} + + + +class C{} +class D extends C { + void foo(D x){ bar(x); } + void bar(C x){} +} 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 bb97132c4c4c..a88744db5441 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java @@ -134,6 +134,7 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase { public void testIDEA72912() throws Exception {doTest(false);} public void testIllegalGenericTypeInInstanceof() throws Exception {doTest(false);} public void testIDEA57339() throws Exception {doTest(false);} + public void testIDEA57340() throws Exception {doTest(false);} public void testJavaUtilCollections_NoVerify() throws Exception { PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule()));