From d5653fd75b1a47a7a56e89935e607f6ea44a4705 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Fri, 26 Sep 2025 17:55:17 +0200 Subject: [PATCH] [java-inspections] IDEA-377764 Incorrect usages of annotations. Annotations can be used for 'throws' lists GitOrigin-RevId: e2d03f73bd84865de29e48d21c492620497e13f3 --- .../resources/messages/JavaAnalysisBundle.properties | 1 + .../nullable/NullableStuffInspectionBase.java | 6 ++++-- .../irrelevantannotations/notnullmarked/Other.java | 2 +- .../irrelevantannotations/nullmarked/Other.java | 2 +- .../irrelevantannotations/nullunmarked/Other.java | 2 +- .../inspection/nullableProblems/IncorrectPlacement.java | 5 +++++ .../codeInspection/JSpecifyConformanceAnnotationTest.java | 8 ++------ 7 files changed, 15 insertions(+), 11 deletions(-) diff --git a/java/java-analysis-api/resources/messages/JavaAnalysisBundle.properties b/java/java-analysis-api/resources/messages/JavaAnalysisBundle.properties index 33b7da6ec372..eb44c8d77404 100644 --- a/java/java-analysis-api/resources/messages/JavaAnalysisBundle.properties +++ b/java/java-analysis-api/resources/messages/JavaAnalysisBundle.properties @@ -254,6 +254,7 @@ inspection.nullable.problems.at.wildcard=Nullability annotation is not applicabl inspection.nullable.problems.at.local.variable=Nullability annotation is not applicable to local variables inspection.nullable.problems.at.type.parameter=Nullability annotation is not applicable to type parameters inspection.nullable.problems.at.reference.list=Nullability annotation is not applicable to extends/implements clause +inspection.nullable.problems.at.throws=Nullability annotation is not applicable to 'throws' clause inspection.nullable.problems.constructor.not.compatible.non.null.type.argument=Constructor is not compatible with a non-null type argument inspection.objects.equals.can.be.simplified.display.name='Objects.equals()' can be replaced with 'equals()' inspection.redundant.cast.problem.descriptor=Casting {0} to #ref #loc is redundant 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 7fdf021d37cd..8201eff3d74c 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 @@ -245,8 +245,7 @@ public class NullableStuffInspectionBase extends AbstractBaseJavaLocalInspection PsiAnnotationOwner owner = annotation.getOwner(); PsiModifierListOwner listOwner = owner instanceof PsiModifierList modifierList ? tryCast(modifierList.getParent(), PsiModifierListOwner.class) : null; - PsiType targetType = listOwner instanceof PsiMethod method ? method.getReturnType() : - listOwner instanceof PsiVariable variable ? variable.getType() : null; + PsiType targetType = listOwner == null ? null : PsiUtil.getTypeByPsiElement(listOwner); if (listOwner != null && targetType != null) { checkRedundantInContainerScope(annotation, manager.findContainerAnnotation(listOwner), nullability); } @@ -298,6 +297,9 @@ public class NullableStuffInspectionBase extends AbstractBaseJavaLocalInspection !(parent.getParent() instanceof PsiTypeParameter)) { reportIncorrectLocation(holder, annotation, listOwner, "inspection.nullable.problems.at.reference.list"); } + if (PsiUtil.isJavaToken(firstChild, JavaTokenType.THROWS_KEYWORD)) { + reportIncorrectLocation(holder, annotation, listOwner, "inspection.nullable.problems.at.throws"); + } } } } diff --git a/java/java-tests/testData/inspection/dataFlow/jspecifyConformance/irrelevantannotations/notnullmarked/Other.java b/java/java-tests/testData/inspection/dataFlow/jspecifyConformance/irrelevantannotations/notnullmarked/Other.java index 96e4839ca093..050b720edddb 100644 --- a/java/java-tests/testData/inspection/dataFlow/jspecifyConformance/irrelevantannotations/notnullmarked/Other.java +++ b/java/java-tests/testData/inspection/dataFlow/jspecifyConformance/irrelevantannotations/notnullmarked/Other.java @@ -104,7 +104,7 @@ public class Other { void throwsN() throws @Nullable Exception; // test:name:NonNull exception type - // test:irrelevant-annotation:NonNulll + // test:irrelevant-annotation:NonNull void throwsR() throws @NonNull Exception; } } diff --git a/java/java-tests/testData/inspection/dataFlow/jspecifyConformance/irrelevantannotations/nullmarked/Other.java b/java/java-tests/testData/inspection/dataFlow/jspecifyConformance/irrelevantannotations/nullmarked/Other.java index 46561336577c..0892e347a54e 100644 --- a/java/java-tests/testData/inspection/dataFlow/jspecifyConformance/irrelevantannotations/nullmarked/Other.java +++ b/java/java-tests/testData/inspection/dataFlow/jspecifyConformance/irrelevantannotations/nullmarked/Other.java @@ -104,7 +104,7 @@ public class Other { void throwsN() throws @Nullable Exception; // test:name:NonNull exception type - // test:irrelevant-annotation:NonNulll + // test:irrelevant-annotation:NonNull void throwsR() throws @NonNull Exception; } } diff --git a/java/java-tests/testData/inspection/dataFlow/jspecifyConformance/irrelevantannotations/nullunmarked/Other.java b/java/java-tests/testData/inspection/dataFlow/jspecifyConformance/irrelevantannotations/nullunmarked/Other.java index 9d0b868d4826..ed0d32f8d66b 100644 --- a/java/java-tests/testData/inspection/dataFlow/jspecifyConformance/irrelevantannotations/nullunmarked/Other.java +++ b/java/java-tests/testData/inspection/dataFlow/jspecifyConformance/irrelevantannotations/nullunmarked/Other.java @@ -106,7 +106,7 @@ public class Other { void throwsN() throws @Nullable Exception; // test:name:NonNull exception type - // test:irrelevant-annotation:NonNulll + // test:irrelevant-annotation:NonNull void throwsR() throws @NonNull Exception; } } diff --git a/java/java-tests/testData/inspection/nullableProblems/IncorrectPlacement.java b/java/java-tests/testData/inspection/nullableProblems/IncorrectPlacement.java index f0fb0d509819..9f603cc2be72 100644 --- a/java/java-tests/testData/inspection/nullableProblems/IncorrectPlacement.java +++ b/java/java-tests/testData/inspection/nullableProblems/IncorrectPlacement.java @@ -2,6 +2,11 @@ import typeUse.*; public class IncorrectPlacement extends @Nullable Object implements @Nullable Cloneable { + + interface X { + void test() throws @Nullable Exception; + void test2() throws @NotNull Exception; + } @Nullable IncorrectPlacement() {} diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/JSpecifyConformanceAnnotationTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/JSpecifyConformanceAnnotationTest.java index ea9719dd1277..357e986a6798 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/JSpecifyConformanceAnnotationTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/JSpecifyConformanceAnnotationTest.java @@ -96,12 +96,7 @@ public class JSpecifyConformanceAnnotationTest extends LightJavaCodeInsightFixtu Pair.create("Irrelevant.java", 46), // see: IDEA-377761 Pair.create("Other.java", 72), // see: IDEA-377763 - Pair.create("Other.java", 70), // see: IDEA-377763 - - Pair.create("Other.java", 102), // see: IDEA-377764 - Pair.create("Other.java", 106), // see: IDEA-377764 - Pair.create("Other.java", 104), // see: IDEA-377764 - Pair.create("Other.java", 108) // see: IDEA-377764 + Pair.create("Other.java", 70) // see: IDEA-377763 ); LineColumn column = StringUtil.offsetToLineColumn(message, offset); return suppressed.contains(Pair.create(fileName, column.line)); @@ -232,6 +227,7 @@ public class JSpecifyConformanceAnnotationTest extends LightJavaCodeInsightFixtu @NotNull String messageKey, Object... args) { switch (messageKey) { case "inspection.nullable.problems.primitive.type.annotation", + "inspection.nullable.problems.at.throws", "inspection.nullable.problems.at.type.parameter", "inspection.nullable.problems.Nullable.NotNull.conflict", "inspection.nullable.problems.at.wildcard",