[java-analysis] Parameter nullability: prefer nullability known from type over nullability known from parameter declaration

Type nullability could be more precise if parameter is generic
Fixes IDEA-364343 False-positive NPE at unboxing inside lambda with JSpecify annotations

GitOrigin-RevId: 9a49f5687eccaa013e639cdf15950be911e100bc
This commit is contained in:
Tagir Valeev
2024-12-06 14:57:38 +00:00
committed by intellij-monorepo-bot
parent 74904a87e5
commit ce18179a78
3 changed files with 32 additions and 5 deletions
@@ -307,12 +307,12 @@ public final class DfaPsiUtil {
if (sam != null) {
PsiParameter parameter = sam.getParameterList().getParameter(index);
if (parameter != null) {
Nullability nullability = getElementNullability(null, parameter);
if (nullability != Nullability.UNKNOWN) {
return nullability;
}
PsiType parameterType = type.resolveGenerics().getSubstitutor().substitute(parameter.getType());
return getTypeNullability(GenericsUtil.eliminateWildcards(parameterType, false, true));
NullabilityAnnotationInfo info = getTypeNullabilityInfo(GenericsUtil.eliminateWildcards(parameterType, false, true));
if (info != null) {
return info.getNullability();
}
return getElementNullability(null, parameter);
}
}
return Nullability.UNKNOWN;
@@ -0,0 +1,21 @@
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
// IDEA-364343
@NullMarked
class AnotherActivity {
public interface ThrowingFunction<T1 extends @Nullable Object, T2 extends @Nullable Object> {
T2 apply(T1 input) throws Throwable;
}
abstract static class Decoder<T extends @Nullable Object> {
abstract <T2 extends @Nullable Object> Decoder<T2> then(
ThrowingFunction<? super T, ? extends T2> dataTransform);
}
native Decoder<Boolean> foo();
Decoder<Boolean> doWork() {
return foo().then(f -> !f);
}
}
@@ -46,4 +46,10 @@ public class DataFlowInspection9Test extends DataFlowInspectionTestCase {
setupTypeUseAnnotations("org.jspecify.annotations", myFixture);
doTest();
}
public void testJSpecifyUnboxingInLambda() {
addJSpecifyNullMarked(myFixture);
setupTypeUseAnnotations("org.jspecify.annotations", myFixture);
doTest();
}
}