diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java index a5cd50713ff3..8387b8cc35d0 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java @@ -45,6 +45,7 @@ import com.intellij.util.Function; import com.intellij.util.IncorrectOperationException; import com.intellij.util.NullableFunction; import com.intellij.util.SmartList; +import com.intellij.util.containers.HashSet; import gnu.trove.THashMap; import gnu.trove.THashSet; import org.jetbrains.annotations.NonNls; @@ -1065,15 +1066,19 @@ public class PsiClassImplUtil { PsiParameter parameter2 = parameters2[i]; PsiType type1 = parameter1.getType(); PsiType type2 = parameter2.getType(); - if (!compareParamTypes(manager, type1, type2)) return false; + if (!compareParamTypes(manager, type1, type2, new HashSet())) return false; } return true; } - private static boolean compareParamTypes(@NotNull PsiManager manager, @NotNull PsiType type1, @NotNull PsiType type2) { + private static boolean compareParamTypes(@NotNull PsiManager manager, @NotNull PsiType type1, @NotNull PsiType type2, Set visited) { if (type1 instanceof PsiArrayType) { - return type2 instanceof PsiArrayType && - compareParamTypes(manager, ((PsiArrayType)type1).getComponentType(), ((PsiArrayType)type2).getComponentType()); + if (type2 instanceof PsiArrayType) { + final PsiType componentType1 = ((PsiArrayType)type1).getComponentType(); + final PsiType componentType2 = ((PsiArrayType)type2).getComponentType(); + if (compareParamTypes(manager, componentType1, componentType2, visited)) return true; + } + return false; } if (!(type1 instanceof PsiClassType) || !(type2 instanceof PsiClassType)) { @@ -1082,10 +1087,23 @@ public class PsiClassImplUtil { PsiClass class1 = ((PsiClassType)type1).resolve(); PsiClass class2 = ((PsiClassType)type2).resolve(); + visited.add(type1.getCanonicalText()); + visited.add(type2.getCanonicalText()); if (class1 instanceof PsiTypeParameter && class2 instanceof PsiTypeParameter) { - return Comparing.equal(class1.getName(), class2.getName()) && - ((PsiTypeParameter)class1).getIndex() == ((PsiTypeParameter)class2).getIndex(); + if (!(Comparing.equal(class1.getName(), class2.getName()) && ((PsiTypeParameter)class1).getIndex() == ((PsiTypeParameter)class2).getIndex())) return false; + final PsiClassType[] eTypes1 = class1.getExtendsListTypes(); + final PsiClassType[] eTypes2 = class2.getExtendsListTypes(); + if (eTypes1.length != eTypes2.length) return false; + for (int i = 0; i < eTypes1.length; i++) { + PsiClassType eType1 = eTypes1[i]; + PsiClassType eType2 = eTypes2[i]; + if (visited.contains(eType1.getCanonicalText()) || visited.contains(eType2.getCanonicalText())) { + return false; + } + if (!compareParamTypes(manager, eType1, eType2, visited)) return false; + } + return true; } return manager.areElementsEquivalent(class1, class2); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/DifferentTypeParamsInOverloadedMethods.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/DifferentTypeParamsInOverloadedMethods.java new file mode 100644 index 000000000000..c44e5554b9cf --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/DifferentTypeParamsInOverloadedMethods.java @@ -0,0 +1,28 @@ +import java.util.*; +class Nav { + interface Sized {} + interface Stream<T> { } + + private static> Stream stream(T entity, int flags) { + System.out.println(entity); + System.out.println(flags); + return null; + } + + private static> Stream stream(T entity, int flags) { + System.out.println(entity); + System.out.println(flags); + return null; + } + + static class A implements Iterable, Sized { + public Iterator iterator() { + return null; + } + } + + public static void main(String[] args) { + Stream aStream = stream(new A(), 0); + System.out.println(aStream); + } +} \ 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 e4e11e04fd58..c1b8ab34b118 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java @@ -190,6 +190,7 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase { public void testTypeArgumentsGivenOnRawType() throws Exception { doTest(false); } public void testTypeArgumentsGivenOnAnonymousClassCreation() throws Exception { doTest(false); } public void _testIDEA94011() throws Exception { doTest(false); } + public void testDifferentTypeParamsInOverloadedMethods() throws Exception { doTest(true); } public void testJavaUtilCollections_NoVerify() throws Exception { PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule()));