mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
red code is green wildcard problems ++(IDEA-66750;IDEA-75178;IDEA-73377)
This commit is contained in:
+1
-43
@@ -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) {
|
||||
|
||||
+44
@@ -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>;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user