From 7805e4dbb7697bfe285dd8492c3ad0e6e7e2904b Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Thu, 4 Aug 2022 13:10:04 +0200 Subject: [PATCH] [java-dfa] IDEA-299239 Pattern nullity handling for Java 19 GitOrigin-RevId: ded6dcdf0f6b1cca8aec4a223290fc231fb67483 --- .../dataFlow/NullabilityProblemKind.java | 8 +++-- .../dataFlow/java/ControlFlowAnalyzer.java | 4 ++- .../dataFlow/fixture/SwitchNullability.java | 30 +++++++++++++++++++ .../DataFlowInspection19Test.java | 3 ++ 4 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 java/java-tests/testData/inspection/dataFlow/fixture/SwitchNullability.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/NullabilityProblemKind.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/NullabilityProblemKind.java index d95db6bca8f6..65aba581e9f0 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/NullabilityProblemKind.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/NullabilityProblemKind.java @@ -7,6 +7,7 @@ import com.intellij.codeInspection.dataFlow.java.ControlFlowAnalyzer; import com.intellij.codeInspection.dataFlow.jvm.problems.JvmDfaProblem; import com.intellij.codeInspection.util.InspectionMessage; import com.intellij.java.analysis.JavaAnalysisBundle; +import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.JavaPsiPatternUtil; @@ -350,8 +351,11 @@ public final class NullabilityProblemKind { if (labelElementList == null) continue; for (PsiCaseLabelElement element : labelElementList.getElements()) { if (element instanceof PsiExpression && TypeConversionUtil.isNullType(((PsiExpression)element).getType())) return null; - if (element instanceof PsiPattern && expressionType != null && - JavaPsiPatternUtil.isTotalForType(element, expressionType)) return null; + if (PsiUtil.getLanguageLevel(element).isLessThan(LanguageLevel.JDK_19_PREVIEW) && + element instanceof PsiPattern && expressionType != null && + JavaPsiPatternUtil.isTotalForType(element, expressionType)) { + return null; + } } } } diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/java/ControlFlowAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/java/ControlFlowAnalyzer.java index 715d7304ae01..95d76fd08f40 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/java/ControlFlowAnalyzer.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/java/ControlFlowAnalyzer.java @@ -36,6 +36,7 @@ import com.intellij.codeInspection.dataFlow.types.DfTypes; import com.intellij.codeInspection.dataFlow.value.*; import com.intellij.codeInspection.dataFlow.value.DfaControlTransferValue.Trap; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.InheritanceUtil; @@ -1115,7 +1116,8 @@ public class ControlFlowAnalyzer extends JavaElementVisitor { addInstruction(new JvmPushInstruction(expressionValue, null)); DeferredOffset condGotoOffset = null; - if (!JavaPsiPatternUtil.isTotalForType(sourcePattern, checkType)) { + if (!JavaPsiPatternUtil.isTotalForType(sourcePattern, checkType) || + !PsiUtil.getLanguageLevel(myCodeFragment).isLessThan(LanguageLevel.JDK_19_PREVIEW)) { addInstruction(new DupInstruction()); addInstruction(new PushValueInstruction(DfTypes.typedObject(JavaPsiPatternUtil.getPatternType(innerPattern), Nullability.NOT_NULL))); diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/SwitchNullability.java b/java/java-tests/testData/inspection/dataFlow/fixture/SwitchNullability.java new file mode 100644 index 000000000000..5372d3cdf14e --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/SwitchNullability.java @@ -0,0 +1,30 @@ +class Test { + void test(Object obj) { + switch (obj) { + case Object o -> { + if (o == null) {} + } + } + if (obj == null) {} + } + + void test2(Object obj) { + switch (obj) { + case null -> {} + case Object o -> { + if (o == null) {} + } + } + if (obj == null) {} + } + + void test3(Object obj) { + switch (obj) { + case Object o -> { + if (o == null) {} + } + case null -> {} + } + if (obj == null) {} + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection19Test.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection19Test.java index d796f6ebbf9b..cb9b08c87c0a 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection19Test.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspection19Test.java @@ -20,4 +20,7 @@ public class DataFlowInspection19Test extends DataFlowInspectionTestCase { public void testWhenPatterns() { doTest(); } + public void testSwitchNullability() { + doTest(); + } } \ No newline at end of file