From 27a0e84a03b3de34ad6380e0aa44efb0271f37cb Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Mon, 13 Jan 2020 15:34:57 +0700 Subject: [PATCH] NullableStuffInspectionBase: fixed support for type-use annotations on arrays EA-220460 - NPE: NullableStuffInspectionBase.checkOverriders GitOrigin-RevId: 2198dd0ff91dd8b1e0a20dc6ce35abc4a26c9fca --- .../nullable/NullableStuffInspectionBase.java | 34 +++++++++++-------- .../TypeUseArrayAnnotation.java | 15 ++++++++ .../NullableStuffInspectionTest.java | 6 ++++ 3 files changed, 40 insertions(+), 15 deletions(-) create mode 100644 java/java-tests/testData/inspection/nullableProblems/TypeUseArrayAnnotation.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 990923350a41..83095877e75b 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 @@ -43,16 +43,16 @@ import static com.intellij.patterns.PsiJavaPatterns.psiMethod; public class NullableStuffInspectionBase extends AbstractBaseJavaLocalInspectionTool { // deprecated fields remain to minimize changes to users inspection profiles (which are often located in version control). - @Deprecated @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NULLABLE_METHOD_OVERRIDES_NOTNULL = true; - @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL = true; - @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE = true; - @Deprecated @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOT_ANNOTATED_PARAMETER_OVERRIDES_NOTNULL = true; - @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOT_ANNOTATED_GETTER = true; - @SuppressWarnings({"WeakerAccess"}) public boolean IGNORE_EXTERNAL_SUPER_NOTNULL; - @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOTNULL_PARAMETERS_OVERRIDES_NOT_ANNOTATED; - @Deprecated @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOT_ANNOTATED_SETTER_PARAMETER = true; - @Deprecated @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS = true; // remains for test - @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NULLS_PASSED_TO_NON_ANNOTATED_METHOD = true; + @Deprecated @SuppressWarnings("WeakerAccess") public boolean REPORT_NULLABLE_METHOD_OVERRIDES_NOTNULL = true; + @SuppressWarnings("WeakerAccess") public boolean REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL = true; + @SuppressWarnings("WeakerAccess") public boolean REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE = true; + @Deprecated @SuppressWarnings("WeakerAccess") public boolean REPORT_NOT_ANNOTATED_PARAMETER_OVERRIDES_NOTNULL = true; + @SuppressWarnings("WeakerAccess") public boolean REPORT_NOT_ANNOTATED_GETTER = true; + @SuppressWarnings("WeakerAccess") public boolean IGNORE_EXTERNAL_SUPER_NOTNULL; + @SuppressWarnings("WeakerAccess") public boolean REPORT_NOTNULL_PARAMETERS_OVERRIDES_NOT_ANNOTATED; + @Deprecated @SuppressWarnings("WeakerAccess") public boolean REPORT_NOT_ANNOTATED_SETTER_PARAMETER = true; + @Deprecated @SuppressWarnings("WeakerAccess") public boolean REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS = true; // remains for test + @SuppressWarnings("WeakerAccess") public boolean REPORT_NULLS_PASSED_TO_NON_ANNOTATED_METHOD = true; public boolean REPORT_NULLS_PASSED_TO_NOT_NULL_PARAMETER = true; private static final Logger LOG = Logger.getInstance(NullableStuffInspectionBase.class); @@ -412,10 +412,10 @@ public class NullableStuffInspectionBase extends AbstractBaseJavaLocalInspection Annotated annotated, NullableNotNullManager manager, String anno, @NotNull ProblemsHolder holder) { if (!AnnotationUtil.isAnnotatingApplicable(field, anno)) { - String message = "Not \'"; + String message = "Not '"; PsiAnnotation annotation = Objects.requireNonNull(annotated.isDeclaredNullable ? annotated.nullable : annotated.notNull); message += annotation.getQualifiedName(); - message += "\' but \'" + anno + "\' would be used for code generation."; + message += "' but '" + anno + "' would be used for code generation."; final PsiJavaCodeReferenceElement annotationNameReferenceElement = annotation.getNameReferenceElement(); holder.registerProblem(annotationNameReferenceElement != null && annotationNameReferenceElement.isPhysical() ? annotationNameReferenceElement : field.getNameIdentifier(), message, @@ -847,7 +847,9 @@ public class NullableStuffInspectionBase extends AbstractBaseJavaLocalInspection && (isNullableNotInferred(overriding, false) || !isNullableNotInferred(overriding, true)) && AddAnnotationPsiFix.isAvailable(overriding, defaultNotNull)) { PsiIdentifier identifier = method.getNameIdentifier();//load tree - PsiAnnotation annotation = AnnotationUtil.findAnnotation(method, nullableManager.getNotNulls()); + NullabilityAnnotationInfo info = nullableManager.findOwnNullabilityInfo(method); + LOG.assertTrue(info != null); + PsiAnnotation annotation = info.getAnnotation(); final String[] annotationsToRemove = ArrayUtilRt.toStringArray(nullableManager.getNullables()); LocalQuickFix fix = AnnotationUtil.isAnnotatingApplicable(overriding, defaultNotNull) @@ -874,9 +876,11 @@ public class NullableStuffInspectionBase extends AbstractBaseJavaLocalInspection !isNullableNotInferred(parameter, false) && AddAnnotationPsiFix.isAvailable(parameter, defaultNotNull)) { PsiIdentifier identifier = parameters[i].getNameIdentifier(); //be sure that corresponding tree element available - PsiAnnotation annotation = AnnotationUtil.findAnnotation(parameters[i], nullableManager.getNotNulls()); + NullabilityAnnotationInfo info = nullableManager.findOwnNullabilityInfo(parameters[i]); + LOG.assertTrue(info != null); + PsiAnnotation annotation = info.getAnnotation(); PsiElement psiElement = annotation; - if (annotation == null || !annotation.isPhysical()) { + if (!annotation.isPhysical()) { psiElement = identifier; if (psiElement == null) continue; } diff --git a/java/java-tests/testData/inspection/nullableProblems/TypeUseArrayAnnotation.java b/java/java-tests/testData/inspection/nullableProblems/TypeUseArrayAnnotation.java new file mode 100644 index 000000000000..cb0c59d838df --- /dev/null +++ b/java/java-tests/testData/inspection/nullableProblems/TypeUseArrayAnnotation.java @@ -0,0 +1,15 @@ +import typeUse.NotNull; + +interface Foo { + String @NotNull [] foo(); + void foo(String @NotNull[] arg); +} +class Bar implements Foo { + public String[] foo() { + return new String[0]; + } + + public void foo(String[] arg) { + + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/NullableStuffInspectionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/NullableStuffInspectionTest.java index 03197c85bf6d..9efbd5278142 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/NullableStuffInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/NullableStuffInspectionTest.java @@ -305,4 +305,10 @@ public class NullableStuffInspectionTest extends LightJavaCodeInsightFixtureTest public void testNullPassedToNullableParameter() { doTest(); } + + public void testTypeUseArrayAnnotation() { + myInspection.REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS = true; + DataFlowInspection8Test.setupTypeUseAnnotations("typeUse", myFixture); + doTest(); + } } \ No newline at end of file