red code is green wildcard problems ++(IDEA-66750;IDEA-75178;IDEA-73377)

This commit is contained in:
anna
2012-03-29 15:17:24 +02:00
parent cfbdc39e46
commit 1563df17f1
4 changed files with 54 additions and 49 deletions
@@ -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();
@@ -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();
@@ -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) {
@@ -172,4 +172,48 @@ class My<T> {
public void test() {
if (getSuperclass() == List.class);
}
}
class IDEA75178 {
void test(Set<String> labels) {
final Matcher<? super Object> empty = isEmpty();
assertThat(labels, empty);
assertAlsoThat(empty, labels);
}
public static <T> void assertThat(T actual, Matcher<T> matcher) { throw new AssertionError(actual.toString() + matcher.toString());}
public static <T> void assertAlsoThat(Matcher<T> matcher, T actual) { throw new AssertionError(actual.toString() + matcher.toString());}
public static <T> Matcher<? super T> isEmpty() {
return null;
}
static class Matcher<<warning descr="Type parameter 'T' is never used">T</warning>>{}
class Foo {}
void testComment() {
Set<Foo> foos = Collections.emptySet();
assertThatComment(foos, hasSize(0));
}
<E> Matcher<? super Collection<? extends E>> hasSize(int size) {return size == 0 ? null : null;}
<T> void assertThatComment(T actual, Matcher<? super T> matcher){ throw new AssertionError(actual.toString() + matcher.toString());}
}
class IDEA66750 {
public void test() {
List<List<String>> data = new ArrayList<List<String>>();
List<List<?>> y = <error descr="Inconvertible types; cannot cast 'java.util.List<java.util.List<java.lang.String>>' to 'java.util.List<java.util.List<?>>'">(List<List<?>>)data</error>;
System.out.println(y);
ArrayList<Number> al = <error descr="Inconvertible types; cannot cast 'java.util.ArrayList<java.lang.Integer>' to 'java.util.ArrayList<java.lang.Number>'">(ArrayList<Number>) new ArrayList<Integer>(1)</error>;
System.out.println(al);
}
}
class IDEA73377 {
public Iterator<Map.Entry<Map.Entry<?, ?>, ?>> iterator(Map<?, ?> map) {
//noinspection unchecked
return <error descr="Inconvertible types; cannot cast 'java.util.Iterator<java.util.Map.Entry<capture<?>,capture<?>>>' to 'java.util.Iterator<java.util.Map.Entry<java.util.Map.Entry<?,?>,?>>'">(Iterator<Map.Entry<Map.Entry<?, ?>, ?>>)map.entrySet().iterator()</error>;
}
}