From 1563df17f1fc1f08f8f4a90843c453aa4faa0910 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 29 Mar 2012 15:15:23 +0200 Subject: [PATCH] red code is green wildcard problems ++(IDEA-66750;IDEA-75178;IDEA-73377) --- .../impl/analysis/GenericsHighlightUtil.java | 44 +------------------ .../intellij/psi/util/TypeConversionUtil.java | 6 +-- .../psi/util/TypesDistinctProver.java | 9 ++-- .../genericsHighlighting/WildcardTypes.java | 44 +++++++++++++++++++ 4 files changed, 54 insertions(+), 49 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java index be5894779a33..d2a350e0d918 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java @@ -688,7 +688,7 @@ public class GenericsHighlightUtil { return true; } } - if (isUncheckedTypeArgumentConversion(lTypeArg, rTypeArg)) return true; + if (!TypeConversionUtil.typesAgree(lTypeArg, rTypeArg, false)) return true; } return false; } @@ -730,48 +730,6 @@ public class GenericsHighlightUtil { return false; } - private static boolean isUncheckedTypeArgumentConversion (PsiType lTypeArg, PsiType rTypeArg) { - if (lTypeArg instanceof PsiPrimitiveType || rTypeArg instanceof PsiPrimitiveType) return false; - if (lTypeArg.equals(rTypeArg)) return false; - if (lTypeArg instanceof PsiCapturedWildcardType) { - //ignore capture conversion - return isUncheckedTypeArgumentConversion(((PsiCapturedWildcardType)lTypeArg).getWildcard(), rTypeArg); - } - if (rTypeArg instanceof PsiCapturedWildcardType) { - //ignore capture conversion - return isUncheckedTypeArgumentConversion(lTypeArg, ((PsiCapturedWildcardType)rTypeArg).getWildcard()); - } - - if (lTypeArg instanceof PsiWildcardType || rTypeArg instanceof PsiWildcardType) { - return !lTypeArg.isAssignableFrom(rTypeArg); - } - - if (lTypeArg instanceof PsiArrayType && rTypeArg instanceof PsiArrayType) { - return isUncheckedTypeArgumentConversion(((PsiArrayType)rTypeArg).getComponentType(), ((PsiArrayType)lTypeArg).getComponentType()); - } - if (lTypeArg instanceof PsiArrayType || rTypeArg instanceof PsiArrayType) return false; - if (lTypeArg instanceof PsiIntersectionType) { - for (PsiType type : ((PsiIntersectionType)lTypeArg).getConjuncts()) { - if (!isUncheckedTypeArgumentConversion(type, rTypeArg)) return false; - } - return true; - } - if (!(lTypeArg instanceof PsiClassType)) { - LOG.error("left: "+lTypeArg + "; "+lTypeArg.getClass()); - } - if (rTypeArg instanceof PsiIntersectionType) { - for (PsiType type : ((PsiIntersectionType)rTypeArg).getConjuncts()) { - if (!isUncheckedTypeArgumentConversion(lTypeArg, type)) return false; - } - return true; - } - if (!(rTypeArg instanceof PsiClassType)) { - LOG.error("right :"+rTypeArg + "; "+rTypeArg.getClass()); - } - return ((PsiClassType)lTypeArg).resolve() instanceof PsiTypeParameter || - ((PsiClassType)rTypeArg).resolve() instanceof PsiTypeParameter; - } - @Nullable public static HighlightInfo checkForeachLoopParameterType(PsiForeachStatement statement) { final PsiParameter parameter = statement.getIterationParameter(); diff --git a/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java b/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java index 7aea5e6cdcdd..557c12198331 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java @@ -354,7 +354,7 @@ public class TypeConversionUtil { final PsiClass class1 = PsiUtil.resolveClassInType(typeArg1); if (class1 instanceof PsiTypeParameter) { for (PsiType type : class1.getExtendsListTypes()) { - if (TypesDistinctProver.provablyDistinct(type, typeArg2)) return false; + if (TypesDistinctProver.provablyDistinct(type, typeArg2) && !isAssignable(type, typeArg2)) return false; } } } @@ -746,7 +746,7 @@ public class TypeConversionUtil { private static boolean isAssignableToWildcard(PsiWildcardType wildcardType, PsiType right) { if (wildcardType.isSuper()) { - return isAssignable(right, wildcardType.getSuperBound()); + return isAssignable(wildcardType.getSuperBound(), right); } return isAssignable(wildcardType.getExtendsBound(), right); } @@ -859,7 +859,7 @@ public class TypeConversionUtil { return true; } - private static boolean typesAgree(PsiType typeLeft, PsiType typeRight, boolean allowUncheckedConversion) { + public static boolean typesAgree(PsiType typeLeft, PsiType typeRight, boolean allowUncheckedConversion) { if (typeLeft instanceof PsiWildcardType) { final PsiWildcardType leftWildcard = (PsiWildcardType)typeLeft; final PsiType leftBound = leftWildcard.getBound(); diff --git a/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java b/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java index 4f86a7039399..4f479fc41c7f 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java +++ b/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java @@ -92,7 +92,10 @@ public class TypesDistinctProver { for (PsiClassType type : parameter.getExtendsListTypes()) { if (!TypeConversionUtil.isAssignable(type, substitutedType1 != null ? substitutedType1 : substitutedType2, false)) return true; } - } else if (provablyDistinct(substitutedType1, substitutedType2)) return true; + } else { + if (provablyDistinct(substitutedType1, substitutedType2)) return true; + if (substitutedType1 instanceof PsiWildcardType && !((PsiWildcardType)substitutedType1).isBounded()) return true; + } } return false; } @@ -100,8 +103,8 @@ public class TypesDistinctProver { final PsiClass boundClass1 = classResolveResult1.getElement(); final PsiClass boundClass2 = classResolveResult2.getElement(); return type2 != null && type1 != null && !type1.equals(type2) && - !InheritanceUtil.isInheritorOrSelf(boundClass1, boundClass2, true) && - !InheritanceUtil.isInheritorOrSelf(boundClass2, boundClass1, true); + (!InheritanceUtil.isInheritorOrSelf(boundClass1, boundClass2, true) || + !InheritanceUtil.isInheritorOrSelf(boundClass2, boundClass1, true)); } public static boolean provablyDistinct(PsiWildcardType type1, PsiWildcardType type2) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/WildcardTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/WildcardTypes.java index 5145e806c4b4..1a586323851c 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/WildcardTypes.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/WildcardTypes.java @@ -172,4 +172,48 @@ class My { public void test() { if (getSuperclass() == List.class); } +} + +class IDEA75178 { + void test(Set labels) { + final Matcher empty = isEmpty(); + assertThat(labels, empty); + assertAlsoThat(empty, labels); + } + + public static void assertThat(T actual, Matcher matcher) { throw new AssertionError(actual.toString() + matcher.toString());} + public static void assertAlsoThat(Matcher matcher, T actual) { throw new AssertionError(actual.toString() + matcher.toString());} + + public static Matcher isEmpty() { + return null; + } + + static class Matcher<T>{} + + class Foo {} + void testComment() { + Set foos = Collections.emptySet(); + assertThatComment(foos, hasSize(0)); + } + + Matcher> hasSize(int size) {return size == 0 ? null : null;} + void assertThatComment(T actual, Matcher matcher){ throw new AssertionError(actual.toString() + matcher.toString());} +} + +class IDEA66750 { + public void test() { + List> data = new ArrayList>(); + List> y = (List>)data; + System.out.println(y); + + ArrayList al = (ArrayList) new ArrayList(1); + System.out.println(al); + } +} + +class IDEA73377 { + public Iterator, ?>> iterator(Map map) { + //noinspection unchecked + return (Iterator, ?>>)map.entrySet().iterator(); + } } \ No newline at end of file