[java-inspections] Report incompatible instantiation

Fixes 'nice to have' parts of IDEA-372223 Nullability inference for generic parameters

GitOrigin-RevId: fe9490c352ee417b8a4146076632ef42790a4d25
This commit is contained in:
Tagir Valeev
2025-06-11 14:40:00 +02:00
committed by intellij-monorepo-bot
parent 4466a6556b
commit b56c24001e
5 changed files with 140 additions and 38 deletions

View File

@@ -192,6 +192,43 @@ public class NullableStuffInspectionBase extends AbstractBaseJavaLocalInspection
}
}
@Override
public void visitMethodCallExpression(@NotNull PsiMethodCallExpression call) {
super.visitMethodCallExpression(call);
PsiReferenceParameterList parameterList = call.getMethodExpression().getParameterList();
if (parameterList == null) return;
PsiType[] parameterization = parameterList.getTypeArguments();
if (parameterization.length == 0) return;
PsiMethod method = call.resolveMethod();
if (method == null) return;
PsiTypeParameter[] typeParameters = method.getTypeParameters();
if (typeParameters.length != parameterization.length) return;
for (int i = 0; i < typeParameters.length; i++) {
PsiTypeParameter typeParameter = typeParameters[i];
PsiType instance = parameterization[i];
TypeNullability nullability = TypeNullability.ofTypeParameter(typeParameter);
if (nullability.nullability() != Nullability.NOT_NULL) continue;
TypeNullability instanceNullability = instance.getNullability();
if (instanceNullability.nullability() == Nullability.NOT_NULL) continue;
NullabilitySource source = instanceNullability.source();
if (source instanceof NullabilitySource.ExplicitAnnotation explicit) {
PsiAnnotation anchor = explicit.annotation();
PsiJavaCodeReferenceElement ref = anchor.getNameReferenceElement();
if (ref != null) {
reportProblem(holder, anchor, "inspection.nullable.problems.nullable.instantiation.of.notnull",
typeParameter.getName(), ref.getReferenceName());
}
} else if (source instanceof NullabilitySource.ContainerAnnotation container) {
PsiElement anchor = parameterList.getTypeParameterElements()[i];
PsiJavaCodeReferenceElement ref = container.annotation().getNameReferenceElement();
if (ref != null) {
reportProblem(holder, anchor, "inspection.nullable.problems.nullable.instantiation.of.notnull.container",
typeParameter.getName(), ref.getReferenceName());
}
}
}
}
@Override
public void visitParameter(@NotNull PsiParameter parameter) {
check(parameter, holder, parameter.getType());
@@ -369,10 +406,7 @@ public class NullableStuffInspectionBase extends AbstractBaseJavaLocalInspection
PsiTypeElement typeArgument = typeArguments[i];
Project project = element.getProject();
PsiType type = typeArgument.getType();
String parameterName = typeParameters[i].getName();
if (parameterName == null) continue;
PsiType parameterType = JavaPsiFacade.getElementFactory(project).createTypeFromText(parameterName, typeParameters[i]);
if (DfaPsiUtil.getTypeNullability(parameterType) != Nullability.NOT_NULL) continue;
if (TypeNullability.ofTypeParameter(typeParameters[i]).nullability() != Nullability.NOT_NULL) continue;
Nullability typeNullability = DfaPsiUtil.getTypeNullability(type);
if (typeNullability != Nullability.NOT_NULL &&
!(typeNullability == Nullability.UNKNOWN && type instanceof PsiWildcardType wildcardType && !wildcardType.isExtends())) {