From 1475442c3f051990c4934fdc34c0c58b50dd296b Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 19 Apr 2016 11:16:32 +0200 Subject: [PATCH] IDEA-154811 Nullable inspection is incorrect with user-defined valueOf static method in Enum --- .../codeInspection/dataFlow/DfaPsiUtil.java | 23 ++++++++++++------- .../dataFlow/fixture/EnumConstantNotNull.java | 14 ++++++++++- 2 files changed, 28 insertions(+), 9 deletions(-) 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 2477f130d167..ed5d849ae81f 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 @@ -73,14 +73,8 @@ public class DfaPsiUtil { 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 (owner instanceof PsiMethod && isEnumValueOf((PsiMethod)owner)) { + return Nullness.NOT_NULL; } if (resultType != null) { @@ -111,6 +105,19 @@ public class DfaPsiUtil { return Nullness.UNKNOWN; } + private static boolean isEnumValueOf(PsiMethod method) { + if ("valueOf".equals(method.getName()) && method.hasModifierProperty(PsiModifier.STATIC)) { + PsiClass containingClass = method.getContainingClass(); + if (containingClass != null && containingClass.isEnum()) { + PsiParameter[] parameters = method.getParameterList().getParameters(); + if (parameters.length == 1 && parameters[0].getType().equalsToText(CommonClassNames.JAVA_LANG_STRING)) { + return true; + } + } + } + return false; + } + public static boolean isInitializedNotNull(PsiField field) { PsiClass containingClass = field.getContainingClass(); if (containingClass == null) return false; diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/EnumConstantNotNull.java b/java/java-tests/testData/inspection/dataFlow/fixture/EnumConstantNotNull.java index 8df81fa8f737..81ee0e6c1932 100644 --- a/java/java-tests/testData/inspection/dataFlow/fixture/EnumConstantNotNull.java +++ b/java/java-tests/testData/inspection/dataFlow/fixture/EnumConstantNotNull.java @@ -16,12 +16,24 @@ class FooWithComments { return AnEnum.valueOf(name) != null; } + boolean checkCustomValueOf(int i) { + return AnEnum.valueOf(i) != null; + } + private native void anotherMethod(String name); @Nullable private native AnEnum nullableGetter(); enum AnEnum { - ENUM_VALUE, FOO2 + ENUM_VALUE, FOO2; + + @Nullable + public static AnEnum valueOf(int i) { + if (i < 0 || i > 1) + return null; + + return values()[i]; + } } }