[Java] IDEA-375132 IDEA-381374 Do not compute nullability conflict for raw types

GitOrigin-RevId: 2796c18626bded813ae5db662b96bb6f55702dc6
This commit is contained in:
Georgii Ustinov
2025-11-05 10:04:00 +00:00
committed by intellij-monorepo-bot
parent 705c560a8a
commit d12ccda981
@@ -21,13 +21,6 @@ import java.util.Set;
*/
@ApiStatus.Internal
public final class JavaTypeNullabilityUtil {
/**
* Java allows recursive type bounds, e.g. {@code class A<T extends A<T>> {}}.
* During the nullability conflict it may turn into the endless recursion.
* This field limits the depth of the recursive type parameters.
*/
private static final int MAX_NULLABILITY_CONFLICT_RECURSION_PARAMETER_DEPTH = 100;
/**
* Computes the class type nullability
*
@@ -114,17 +107,13 @@ public final class JavaTypeNullabilityUtil {
public static @NotNull NullabilityConflict getNullabilityConflictInAssignment(@Nullable PsiType leftType,
@Nullable PsiType rightType,
boolean checkNotNullToNull) {
return getNullabilityConflictInAssignment(leftType, rightType, 0, checkNotNullToNull, false);
return getNullabilityConflictInAssignment(leftType, rightType, checkNotNullToNull, false);
}
private static @NotNull NullabilityConflict getNullabilityConflictInAssignment(@Nullable PsiType leftType,
@Nullable PsiType rightType,
int recursionDepth,
boolean checkNotNullToNull,
boolean checkConflictInInitialType) {
if (recursionDepth >= MAX_NULLABILITY_CONFLICT_RECURSION_PARAMETER_DEPTH) {
return NullabilityConflict.UNKNOWN;
}
if (checkConflictInInitialType) {
NullabilityConflict nullabilityConflict = getNullabilityConflictType(leftType, rightType);
if (isAllowedNullabilityConflictType(checkNotNullToNull, nullabilityConflict)) return nullabilityConflict;
@@ -137,34 +126,34 @@ public final class JavaTypeNullabilityUtil {
}
if (rightType instanceof PsiIntersectionType) {
return getNullabilityConflictInTypeArguments(leftType, rightType, recursionDepth, checkNotNullToNull);
return getNullabilityConflictInTypeArguments(leftType, rightType, checkNotNullToNull);
}
if (rightType instanceof PsiCapturedWildcardType) {
return getNullabilityConflictInAssignment(leftType, ((PsiCapturedWildcardType)rightType).getUpperBound(true), recursionDepth + 1, checkNotNullToNull,
return getNullabilityConflictInAssignment(leftType, ((PsiCapturedWildcardType)rightType).getUpperBound(true), checkNotNullToNull,
false);
}
if (leftType instanceof PsiCapturedWildcardType) {
return getNullabilityConflictInAssignment(((PsiCapturedWildcardType)leftType).getLowerBound(), rightType, recursionDepth + 1, checkNotNullToNull, false);
return getNullabilityConflictInAssignment(((PsiCapturedWildcardType)leftType).getLowerBound(), rightType, checkNotNullToNull, false);
}
if (leftType instanceof PsiWildcardType) {
return getNullabilityConflictInAssignment(GenericsUtil.getWildcardBound(leftType), rightType, recursionDepth + 1, checkNotNullToNull, false);
return getNullabilityConflictInAssignment(GenericsUtil.getWildcardBound(leftType), rightType, checkNotNullToNull, false);
}
if (rightType instanceof PsiWildcardType) {
return getNullabilityConflictInAssignment(leftType, GenericsUtil.getWildcardBound(rightType), recursionDepth + 1, checkNotNullToNull, false);
return getNullabilityConflictInAssignment(leftType, GenericsUtil.getWildcardBound(rightType), checkNotNullToNull, false);
}
if (leftType instanceof PsiArrayType && rightType instanceof PsiArrayType) {
return getNullabilityConflictInAssignment(((PsiArrayType)leftType).getComponentType(),
((PsiArrayType)rightType).getComponentType(), recursionDepth + 1, checkNotNullToNull, true);
((PsiArrayType)rightType).getComponentType(), checkNotNullToNull, true);
}
if (!(leftType instanceof PsiClassType) || !(rightType instanceof PsiClassType)) {
return NullabilityConflict.UNKNOWN;
}
return getNullabilityConflictInTypeArguments(leftType, rightType, recursionDepth, checkNotNullToNull);
return getNullabilityConflictInTypeArguments(leftType, rightType, checkNotNullToNull);
}
/**
@@ -178,10 +167,11 @@ public final class JavaTypeNullabilityUtil {
*/
private static @NotNull NullabilityConflict getNullabilityConflictInTypeArguments(@NotNull PsiType leftType,
@NotNull PsiType rightType,
int recursionDepth,
boolean checkNotNullToNull) {
if (isRawType(leftType) || isRawType(rightType)) return NullabilityConflict.UNKNOWN;
PsiClass leftClass = PsiTypesUtil.getPsiClass(leftType);
if (leftClass == null) return NullabilityConflict.UNKNOWN;
List<PsiType> leftParameterTypeList = getParentParameterTypeListFromDerivedType(leftType, leftClass);
List<PsiType> rightParameterTypeList = getParentParameterTypeListFromDerivedType(rightType, leftClass);
if (leftParameterTypeList == null ||
@@ -197,7 +187,6 @@ public final class JavaTypeNullabilityUtil {
NullabilityConflict nullabilityConflict = getNullabilityConflictInAssignment(
leftParameterType,
rightParameterType,
recursionDepth + 1,
checkNotNullToNull,
true
);
@@ -207,6 +196,10 @@ public final class JavaTypeNullabilityUtil {
return NullabilityConflict.UNKNOWN;
}
private static boolean isRawType(@NotNull PsiType type) {
return type instanceof PsiClassType && ((PsiClassType)type).isRaw();
}
private static @Nullable List<@NotNull PsiType> getParentParameterTypeListFromDerivedType(@NotNull PsiType derivedType,
@NotNull PsiClass superClass) {
if (derivedType instanceof PsiIntersectionType) {