From c1fdc02b1a398c16898ac7dbd0e8d0ff78a18c9f Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 10 Feb 2016 11:18:14 +0100 Subject: [PATCH] Enum.valueOf and annotations methods are not-null (IDEA-151305, IDEA-151174) --- .../intellij/codeInspection/dataFlow/DfaPsiUtil.java | 11 ++++++++++- .../dataFlow/fixture/AnnotationMethodNotNull.java | 11 +++++++++++ .../dataFlow/fixture/EnumConstantNotNull.java | 4 ++++ .../codeInspection/DataFlowInspectionTest.java | 2 ++ 4 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/inspection/dataFlow/fixture/AnnotationMethodNotNull.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaPsiUtil.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaPsiUtil.java index 0e5c8d6bb79f..8bdc0e8c7eec 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaPsiUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaPsiUtil.java @@ -70,9 +70,18 @@ public class DfaPsiUtil { return Nullness.UNKNOWN; } - if (owner instanceof PsiEnumConstant) { + if (owner instanceof PsiEnumConstant || PsiUtil.isAnnotationMethod(owner)) { return Nullness.NOT_NULL; } + if (owner instanceof PsiMethod) { + PsiMethod method = (PsiMethod)owner; + if ("valueOf".equals(method.getName()) && method.hasModifierProperty(PsiModifier.STATIC)) { + PsiClass containingClass = method.getContainingClass(); + if (containingClass != null && containingClass.isEnum()) { + return Nullness.NOT_NULL; + } + } + } if (resultType != null) { NullableNotNullManager nnn = NullableNotNullManager.getInstance(owner.getProject()); diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/AnnotationMethodNotNull.java b/java/java-tests/testData/inspection/dataFlow/fixture/AnnotationMethodNotNull.java new file mode 100644 index 000000000000..d911a9430a23 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/AnnotationMethodNotNull.java @@ -0,0 +1,11 @@ +class Test { + @interface FooBar { + String x(); + } + + static void baz(FooBar annotation) { + if (annotation.x() == null) { + System.out.println("null"); + } + } +} diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/EnumConstantNotNull.java b/java/java-tests/testData/inspection/dataFlow/fixture/EnumConstantNotNull.java index c9b2f78b2a96..8df81fa8f737 100644 --- a/java/java-tests/testData/inspection/dataFlow/fixture/EnumConstantNotNull.java +++ b/java/java-tests/testData/inspection/dataFlow/fixture/EnumConstantNotNull.java @@ -12,6 +12,10 @@ class FooWithComments { } } + boolean checkValueOf(String name) { + return AnEnum.valueOf(name) != null; + } + private native void anotherMethod(String name); @Nullable diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java index 55a57e1fa648..a34094eba571 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java @@ -91,6 +91,8 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase { public void testGreaterIsNotEquals() throws Throwable { doTest(); } public void testNotGreaterIsNotEquals() throws Throwable { doTest(); } + public void testAnnotationMethodNotNull() { doTest(); } + public void testChainedFinalFieldsDfa() throws Throwable { doTest(); } public void testFinalFieldsDifferentInstances() throws Throwable { doTest(); } public void testThisFieldGetters() throws Throwable { doTest(); }