From 823e008db1f4f90db2da5698754ee1e3d08d8d0c Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 17 Jul 2013 18:38:25 +0200 Subject: [PATCH] calculate bound based on all type arguments (IDEA-57334) --- .../source/resolve/PsiResolveHelperImpl.java | 32 +++++++++++++-- .../genericsHighlighting/IDEA57334.java | 41 +++++++++++++++++++ .../daemon/GenericsHighlightingTest.java | 4 ++ 3 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA57334.java 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 49f44e3cc22c..2ed9d59bd23c 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 @@ -929,6 +929,8 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { return inferBySubtypingConstraint(patternType, constraintType, depth, paramClass, argClass); } + PsiType lowerBound = PsiType.NULL; + PsiType upperBound = PsiType.NULL; Pair wildcardCaptured = null; for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(paramClass)) { PsiType paramType = paramResult.getSubstitutor().substitute(typeParameter); @@ -950,13 +952,35 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { Pair res = getSubstitutionForTypeParameterInner(paramType, argType, patternType, ConstraintType.EQUALS, depth + 1); if (res != null) { - PsiType type = res.getFirst(); - if (!(type instanceof PsiWildcardType)) return res; - if (wildcardCaptured != null) return FAILED_INFERENCE; - wildcardCaptured = res; + final PsiType type = res.getFirst(); + switch (res.getSecond()) { + case EQUALS: + if (!(type instanceof PsiWildcardType)) return res; + if (wildcardCaptured != null) return FAILED_INFERENCE; + wildcardCaptured = res; + break; + case SUPERTYPE: + wildcardCaptured = res; + if (PsiType.NULL.equals(lowerBound)) { + lowerBound = type; + } + else if (!lowerBound.equals(type)) { + lowerBound = GenericsUtil.getLeastUpperBound(lowerBound, type, typeParameter.getManager()); + if (lowerBound == null) return FAILED_INFERENCE; + } + break; + case SUBTYPE: + wildcardCaptured = res; + if (PsiType.NULL.equals(upperBound) || TypeConversionUtil.isAssignable(upperBound, type)) { + upperBound = type; + } + } } } + if (lowerBound != PsiType.NULL) return new Pair(lowerBound, ConstraintType.SUPERTYPE); + if (upperBound != PsiType.NULL) return new Pair(upperBound, ConstraintType.SUBTYPE); + return wildcardCaptured; } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA57334.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA57334.java new file mode 100644 index 000000000000..ece1dd102757 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA57334.java @@ -0,0 +1,41 @@ +abstract class A { + abstract void foo(A x); + void bar(A x){ + foo(x); + } +} + +abstract class A0 { + abstract void foo(A0 x); + void bar(A0 x){ + foo(x); + } +} + +abstract class A1 { + abstract void foo(A1 x); + void bar(A1 x){ + foo(x); + } +} + +abstract class A10 { + abstract void foo(A10 x); + void bar(A10 x){ + foo(x); + } +} + +abstract class A2 { + abstract void foo(A2 x); + void bar(A2 x){ + foo(x); + } +} + +abstract class A20 { + abstract void foo(A20 x); + void bar(A20 x){ + foo(x); + } +} \ 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 ed1769bb46dc..186dce28e782 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java @@ -291,6 +291,10 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase { public void testIDEA104160() {doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false);} public void testSOEInLeastUpperClass() {doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false);} + public void testIDEA57334() { + doTest5(false); + } + public void testJavaUtilCollections_NoVerify() throws Exception { PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule())); assertNotNull(collectionsClass);