From 32094bf637d8726f6b3e33fd4678ad05e74d78ba Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 28 Jan 2014 14:27:56 +0400 Subject: [PATCH] temp solution (IDEA-118527) --- .../JavaMethodsConflictResolver.java | 68 ++++++++++++++++--- .../genericsHighlighting/IDEA118527.java | 48 +++++++++++++ .../daemon/GenericsHighlightingTest.java | 1 + 3 files changed, 109 insertions(+), 8 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA118527.java diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java index 7b4f9a412891..eaaa8b8d475c 100644 --- a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java +++ b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java @@ -28,6 +28,10 @@ import com.intellij.psi.infos.MethodCandidateInfo; import com.intellij.psi.scope.PsiConflictResolver; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.*; +import com.intellij.util.ArrayUtil; +import com.intellij.util.ArrayUtilRt; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashSet; import gnu.trove.THashMap; import gnu.trove.THashSet; @@ -35,10 +39,7 @@ import gnu.trove.TIntArrayList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; /** * Created by IntelliJ IDEA. @@ -506,10 +507,11 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ final PsiSubstitutor siteSubstitutor1 = ((MethodCandidateInfo)info1).getSiteSubstitutor(); final PsiSubstitutor siteSubstitutor2 = ((MethodCandidateInfo)info2).getSiteSubstitutor(); - final PsiType[] types2AtSite = typesAtSite(types2, siteSubstitutor2); - final PsiType[] types1AtSite = typesAtSite(types1, siteSubstitutor1); + final PsiType[] types2AtSite = typesAtSite(types2, siteSubstitutor2, typeParameters2); + final PsiType[] types1AtSite = typesAtSite(types1, siteSubstitutor1, typeParameters1); - final PsiSubstitutor methodSubstitutor1 = calculateMethodSubstitutor(typeParameters1, method1, siteSubstitutor1, types1, types2AtSite, languageLevel); + final PsiSubstitutor methodSubstitutor1 = calculateMethodSubstitutor(typeParameters1, method1, siteSubstitutor1, types1, types2AtSite, + languageLevel); boolean applicable12 = isApplicableTo(types2AtSite, method1, languageLevel, varargsPosition, methodSubstitutor1); final PsiSubstitutor methodSubstitutor2 = calculateMethodSubstitutor(typeParameters2, method2, siteSubstitutor2, types2, types1AtSite, languageLevel); @@ -641,14 +643,64 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ return applicabilityLevel > MethodCandidateInfo.ApplicabilityLevel.NOT_APPLICABLE; } - private static PsiType[] typesAtSite(PsiType[] types1, PsiSubstitutor siteSubstitutor1) { + private static PsiType[] typesAtSite(PsiType[] types1, PsiSubstitutor siteSubstitutor1, PsiTypeParameter[] typeParameters1) { final PsiType[] types = PsiType.createArray(types1.length); for (int i = 0; i < types1.length; i++) { types[i] = siteSubstitutor1.substitute(types1[i]); + if (types[i] instanceof PsiClassType) { + final PsiClass aClass = ((PsiClassType)types[i]).resolve(); + if (aClass instanceof PsiTypeParameter) { + final List resultBounds = new ArrayList(); + for (PsiType bound : aClass.getExtendsListTypes()) { + bound = siteSubstitutor1.substitute(bound); + if (!dependsOnOtherTypeParams(bound, typeParameters1)) { + resultBounds.add(bound); + } else { + resultBounds.clear(); + break; + } + } + if (!resultBounds.isEmpty()) { + types[i] = PsiIntersectionType.createIntersection(resultBounds); + } + } + } } return types; } + private static boolean dependsOnOtherTypeParams(PsiType type, final PsiTypeParameter[] params) { + return type.accept(new PsiTypeVisitor(){ + @Nullable + @Override + public Boolean visitClassType(PsiClassType classType) { + for (PsiType psiType : classType.getParameters()) { + if (psiType.accept(this)) return true; + } + return ArrayUtilRt.find(params, classType.resolve()) > -1; + } + + @Nullable + @Override + public Boolean visitArrayType(PsiArrayType arrayType) { + return arrayType.getComponentType().accept(this); + } + + @Nullable + @Override + public Boolean visitWildcardType(PsiWildcardType wildcardType) { + final PsiType bound = wildcardType.getBound(); + return bound != null && bound.accept(this); + } + + @Nullable + @Override + public Boolean visitType(PsiType type) { + return false; + } + }); + } + private static PsiSubstitutor calculateMethodSubstitutor(final PsiTypeParameter[] typeParameters, final PsiMethod method, final PsiSubstitutor siteSubstitutor, diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA118527.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA118527.java new file mode 100644 index 000000000000..a365bad22464 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA118527.java @@ -0,0 +1,48 @@ + +interface Listener {} +class Adapter implements Listener {} +class Super { + public > C apply(C configurer) throws Exception { + return null; + } + + public > C apply(C configurer) throws Exception { + return null; + } +} + +class AdapterImpl extends Adapter{} + +class Child extends Super {} +class D { + + void foo(Child ch, AdapterImpl a) throws Exception { + ch.apply(a); + } +} + +class Test { + interface Listener {} + class Adapter implements Listener {} + class Super { + public & Runnable> C apply(C configurer) throws Exception { + return null; + } + + public & Runnable> C apply(C configurer) throws Exception { + return null; + } + } + + abstract class AdapterImpl extends Adapter implements Runnable{} + + class Child extends Super {} + class D { + + void foo(Child ch, AdapterImpl a) throws Exception { + ch.apply( a); + } + } + + +} \ 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 164ef314bea4..f0cac18d908e 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java @@ -335,6 +335,7 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase { public void testIDEA117827() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } public void testIDEA118037() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } public void testIDEA119546() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } + public void testIDEA118527() { 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()));