[java-inspections] part of IDEA-380832

- support taking into account nullability of type parameter of class

GitOrigin-RevId: fb7296c039189816591014e435cc30bdb5118e14
This commit is contained in:
Mikhail Pyltsin
2025-11-20 08:44:21 +00:00
committed by intellij-monorepo-bot
parent e567b53279
commit 0ecc455ce9
3 changed files with 73 additions and 1 deletions
@@ -221,7 +221,10 @@ public final class PsiSubstitutorImpl implements PsiSubstitutor {
while (true) {
final PsiTypeParameter[] params = resolve.getTypeParameters();
for (final PsiTypeParameter param : params) {
final PsiType original = originalSubstitutor.substitute(param);
PsiType original = originalSubstitutor.substitute(param);
if (original != null && original.getNullability().equals(TypeNullability.UNKNOWN)) {
original = original.withNullability(TypeNullability.ofTypeParameter(param));
}
PsiType mapping = original == null ? null : original.accept(this);
substMap = substMap.with(param, mapping);
}
@@ -0,0 +1,63 @@
package org.example;
import org.jspecify.annotations.*;
@NullMarked
class CustomOptionalTest2 {
@Nullable
public String a;
public String @Nullable [] a3;
CustomOptional2<String> returnNotNullableDelegate() {
return Delegate2.ofNullable(a);
}
CustomOptional2<String> returnNotNullableDelegate2() {
return Delegate2.ofNullable2(a);
}
CustomOptional2<String[]> returnNotNullableDelegate3() {
return Delegate2.ofNullable3(a3);
}
CustomOptional2<?> returnNotNullableDelegate4() {
return Delegate2.ofNullable4(a3);
}
CustomOptional2<?> returnNotNullableDelegate5() {
return Delegate2.ofNullable4(a3);
}
}
class Delegate2 {
static <T> CustomOptional2<T> ofNullable(@Nullable T t) {
return CustomOptional2.ofNullable(t);
}
static CustomOptional2<String> ofNullable2(@Nullable String t) {
return CustomOptional2.ofNullable(t);
}
static CustomOptional2<String[]> ofNullable3(@Nullable String @Nullable [] t) {
return CustomOptional2.ofNullable(t);
}
static <T extends Object> CustomOptional2<? extends T> ofNullable4(T t) {
return CustomOptional2.ofNullable(t);
}
static CustomOptional2<?> ofNullable5(Object t) {
return CustomOptional2.ofNullable(t);
}
}
class CustomOptional2<T extends @NotNull Object> {
public CustomOptional2(T s) {
}
public static <T> CustomOptional2<@NotNull T> ofNullable(@Nullable T value) {
return value == null ? (CustomOptional2<T>) new CustomOptional2<>("")
: new CustomOptional2<>(value);
}
}
@@ -256,6 +256,12 @@ public class DataFlowInspection8Test extends DataFlowInspectionTestCase {
public void testFlatMapSideEffect() { doTest(); }
public void testOptionalValueTracking() { doTest(); }
public void testOptionalAsQualifier() { doTest(); }
public void testDelegateClassTypeParameter() {
addJSpecifyNullMarked(myFixture);
setupTypeUseAnnotations("org.jspecify.annotations", myFixture);
doTest();
}
public void testClearZeroesSize() { doTest(); }
public void testLambdaInlineReassignReturnWithDeeperEquality() { doTest(); }