From 1ad36b0e7aed48f237a9a411053e2135e415f15f Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Tue, 25 Feb 2025 18:26:16 +0100 Subject: [PATCH] [java-dfa] IDEA-365459 "Treat non-annotated members and parameters as @Nullable" inspections makes constructors @Nullable GitOrigin-RevId: b4c0234154171b658451e9628fd1bbc873e4699f --- .../java/inst/MethodReferenceInstruction.java | 15 +++++++++- .../NewMethodReferenceMustBeNonNull.java | 28 +++++++++++++++++++ .../DataFlowInspection8Test.java | 3 ++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/inspection/dataFlow/fixture/NewMethodReferenceMustBeNonNull.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/java/inst/MethodReferenceInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/java/inst/MethodReferenceInstruction.java index cb8d53f21fb5..fe6512b06c9a 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/java/inst/MethodReferenceInstruction.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/java/inst/MethodReferenceInstruction.java @@ -10,6 +10,8 @@ import com.intellij.codeInspection.dataFlow.java.anchor.JavaMethodReferenceRetur import com.intellij.codeInspection.dataFlow.lang.ir.DfaInstructionState; import com.intellij.codeInspection.dataFlow.lang.ir.ExpressionPushingInstruction; import com.intellij.codeInspection.dataFlow.memory.DfaMemoryState; +import com.intellij.codeInspection.dataFlow.types.DfType; +import com.intellij.codeInspection.dataFlow.types.DfTypes; import com.intellij.codeInspection.dataFlow.value.DfaValue; import com.intellij.psi.*; import com.intellij.psi.util.TypeConversionUtil; @@ -63,7 +65,18 @@ public class MethodReferenceInstruction extends ExpressionPushingInstruction { } List contracts = JavaMethodContractUtil.getMethodCallContracts(method, null); PsiType returnType = substitutor.substitute(method.getReturnType()); - DfaValue defaultResult = interpreter.getFactory().fromDfType(typedObject(returnType, DfaPsiUtil.getElementNullability(returnType, method))); + DfType dfType; + if (method.isConstructor()) { + PsiClass containingClass = method.getContainingClass(); + if (containingClass != null) { + dfType = TypeConstraints.exactClass(containingClass).asDfType().meet(DfTypes.NOT_NULL_OBJECT); + } else { + dfType = DfTypes.NOT_NULL_OBJECT; + } + } else { + dfType = typedObject(returnType, DfaPsiUtil.getElementNullability(returnType, method)); + } + DfaValue defaultResult = interpreter.getFactory().fromDfType(dfType); Nullability expectedNullability = DfaPsiUtil.getTypeNullability(LambdaUtil.getFunctionalInterfaceReturnType(methodRef)); if (expectedNullability == Nullability.NOT_NULL) { CheckNotNullInstruction.checkNotNullable(interpreter, state, defaultResult, diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/NewMethodReferenceMustBeNonNull.java b/java/java-tests/testData/inspection/dataFlow/fixture/NewMethodReferenceMustBeNonNull.java new file mode 100644 index 000000000000..db738d9e5b2e --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/NewMethodReferenceMustBeNonNull.java @@ -0,0 +1,28 @@ +import org.jetbrains.annotations.NotNull; +import java.util.function.Function; +import java.util.function.Supplier; + +class Main { + public static void main(String[] args) { + System.out.println("Hello, World!"); + + useConstructorAsFunction(InnerClass::new); + useConstructorAsSupplier(InnerClass::new); + } + + public static void useConstructorAsFunction(@NotNull Function<@NotNull String, @NotNull InnerClass> function) { + + } + + public static void useConstructorAsSupplier(@NotNull Supplier<@NotNull InnerClass> supplier) { + + } + + public static class InnerClass { + public InnerClass(@NotNull String name) { + } + + public InnerClass() { + } + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java index 4e1fc870fa29..b022e0f4ab6d 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection8Test.java @@ -381,4 +381,7 @@ public class DataFlowInspection8Test extends DataFlowInspectionTestCase { doTest(); } public void testFieldWriteInLambda() { doTest(); } + public void testNewMethodReferenceMustBeNonNull() { + doTestWith((insp, __) -> insp.TREAT_UNKNOWN_MEMBERS_AS_NULLABLE = true); + } } \ No newline at end of file