From e8ac7110c0dd7c228c3ae3059ddfa94334fd0794 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 28 Mar 2017 18:25:41 +0200 Subject: [PATCH] IDEA-170214 Properly handle Bean Validation inheritance in @NotNull/@Nullable problems inspection --- .../nullable/NullableStuffInspectionBase.java | 13 +++++++++---- .../nullableProblems/BeanValidationNotNull.java | 13 +++++++++++++ .../codeInspection/NullableStuffInspectionTest.java | 9 ++++++++- 3 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 java/java-tests/testData/inspection/nullableProblems/BeanValidationNotNull.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java index f82c948ee070..08e7257d722f 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java @@ -479,7 +479,12 @@ public class NullableStuffInspectionBase extends BaseJavaBatchLocalInspectionToo !(method.getReturnType() instanceof PsiPrimitiveType) && !method.isConstructor() && !getNullityManager(method).hasNullability(method) && - isNotNullNotInferred(superMethod, true, IGNORE_EXTERNAL_SUPER_NOTNULL); + isNotNullNotInferred(superMethod, true, IGNORE_EXTERNAL_SUPER_NOTNULL) && + !hasInheritableNotNull(superMethod); + } + + private static boolean hasInheritableNotNull(PsiModifierListOwner owner) { + return AnnotationUtil.isAnnotated(owner, "javax.annotation.constraints.NotNull", true); } private void checkParameters(PsiMethod method, @@ -515,7 +520,7 @@ public class NullableStuffInspectionBase extends BaseJavaBatchLocalInspectionToo } if (REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL) { for (PsiParameter superParameter : superParameters) { - if (!nullableManager.hasNullability(parameter) && isNotNullNotInferred(superParameter, false, IGNORE_EXTERNAL_SUPER_NOTNULL)) { + if (!nullableManager.hasNullability(parameter) && isNotNullNotInferred(superParameter, false, IGNORE_EXTERNAL_SUPER_NOTNULL) && !hasInheritableNotNull(superParameter)) { final LocalQuickFix fix = AnnotationUtil.isAnnotatingApplicable(parameter, nullableManager.getDefaultNotNull()) ? new AddNotNullAnnotationFix(parameter) : createChangeDefaultNotNullFix(nullableManager, superParameter); @@ -576,10 +581,10 @@ public class NullableStuffInspectionBase extends BaseJavaBatchLocalInspectionToo boolean hasAnnotatedParameter = false; for (int i = 0; i < parameters.length; i++) { PsiParameter parameter = parameters[i]; - parameterAnnotated[i] = isNotNullNotInferred(parameter, false, false); + parameterAnnotated[i] = isNotNullNotInferred(parameter, false, false) && !hasInheritableNotNull(parameter); hasAnnotatedParameter |= parameterAnnotated[i]; } - if (hasAnnotatedParameter || annotated.isDeclaredNotNull) { + if (hasAnnotatedParameter || annotated.isDeclaredNotNull && !hasInheritableNotNull(method)) { PsiManager manager = method.getManager(); final String defaultNotNull = nullableManager.getDefaultNotNull(); final boolean superMethodApplicable = AnnotationUtil.isAnnotatingApplicable(method, defaultNotNull); diff --git a/java/java-tests/testData/inspection/nullableProblems/BeanValidationNotNull.java b/java/java-tests/testData/inspection/nullableProblems/BeanValidationNotNull.java new file mode 100644 index 000000000000..f8365f8741a5 --- /dev/null +++ b/java/java-tests/testData/inspection/nullableProblems/BeanValidationNotNull.java @@ -0,0 +1,13 @@ +import javax.annotation.constraints.*; + +interface Intf { + @NotNull Object foo(@NotNull Object p); +} + +class Impl implements Intf { + @Override + public Object foo(Object p) { + return p; + } + +} diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/NullableStuffInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/NullableStuffInspectionTest.java index a8a9140d4338..96e934844885 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/NullableStuffInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/NullableStuffInspectionTest.java @@ -115,7 +115,7 @@ public class NullableStuffInspectionTest extends LightCodeInsightFixtureTestCase DataFlowInspectionTest.addJavaxDefaultNullabilityAnnotations(myFixture); myFixture.addFileToProject("foo/package-info.java", "@javax.annotation.ParametersAreNonnullByDefault package foo;"); - myFixture.addClass("import javax.annotation.*; package foo; public interface NullableFunction { void fun(@Nullable Object o); }"); + myFixture.addClass("package foo; import javax.annotation.*; public interface NullableFunction { void fun(@Nullable Object o); }"); myFixture.addClass("package foo; public interface AnyFunction { void fun(Object o); }"); doTest(); @@ -195,4 +195,11 @@ public class NullableStuffInspectionTest extends LightCodeInsightFixtureTestCase myFixture.checkHighlighting(true, false, true); } + public void testBeanValidationNotNull() { + myFixture.addClass("package javax.annotation.constraints; public @interface NotNull{}"); + DataFlowInspection8Test.setCustomAnnotations(getProject(), getTestRootDisposable(), "javax.annotation.constraints.NotNull", "javax.annotation.constraints.Nullable"); + myInspection.REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS = true; + doTest(); + } + } \ No newline at end of file