From 0c91f2472cb187192e6b5f7bf77570999190d51c Mon Sep 17 00:00:00 2001 From: "Kukzze ." Date: Wed, 28 Oct 2026 10:37:30 +0530 Subject: [PATCH] Fix RedundantNullabilityCheck for nested types --- .../checks/RedundantNullabilityCheck.java | 14 ++++++-- .../checks/TestRedundantNullabilityCheck.java | 17 +++++++++ .../java/testdata/RedundantNullability.java | 36 +++++++++++++++++++ 3 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 paper-checkstyle/src/test/java/io/papermc/checkstyle/checks/TestRedundantNullabilityCheck.java create mode 100644 paper-checkstyle/src/testData/java/testdata/RedundantNullability.java diff --git a/paper-checkstyle/src/main/java/io/papermc/checkstyle/checks/RedundantNullabilityCheck.java b/paper-checkstyle/src/main/java/io/papermc/checkstyle/checks/RedundantNullabilityCheck.java index 1ed6c695519a..40db9c36e36b 100644 --- a/paper-checkstyle/src/main/java/io/papermc/checkstyle/checks/RedundantNullabilityCheck.java +++ b/paper-checkstyle/src/main/java/io/papermc/checkstyle/checks/RedundantNullabilityCheck.java @@ -31,10 +31,20 @@ public int[] getRequiredTokens() { @Override public void visitToken(final DetailAST ast) { - final boolean pkgIsNullMarked = Util.isPackageInfoAnnotated(Path.of(this.getFilePath()), NullabilityAnnotationsCheck::isNullMarkedAnnotation); final DetailAST nullMarkedAnnotation = NullabilityAnnotationsCheck.getNullMarkedAnnotation(ast); - if (pkgIsNullMarked && nullMarkedAnnotation != null) { + if (nullMarkedAnnotation == null) { + return; + } + final boolean pkgIsNullMarked = Util.isPackageInfoAnnotated(Path.of(this.getFilePath()), NullabilityAnnotationsCheck::isNullMarkedAnnotation); + if (pkgIsNullMarked) { this.log(nullMarkedAnnotation.getLineNo(), ast.getColumnNo() - 1, "Redundant NullMarked annotation"); + return; + } + for (DetailAST parentDef = Util.getEnclosingTypeDeclaration(ast); parentDef != null; parentDef = Util.getEnclosingTypeDeclaration(parentDef)) { + if (NullabilityAnnotationsCheck.getNullMarkedAnnotation(parentDef) != null) { + this.log(nullMarkedAnnotation.getLineNo(), ast.getColumnNo() - 1, "Redundant NullMarked annotation"); + return; + } } } } diff --git a/paper-checkstyle/src/test/java/io/papermc/checkstyle/checks/TestRedundantNullabilityCheck.java b/paper-checkstyle/src/test/java/io/papermc/checkstyle/checks/TestRedundantNullabilityCheck.java new file mode 100644 index 000000000000..e175bf96ac23 --- /dev/null +++ b/paper-checkstyle/src/test/java/io/papermc/checkstyle/checks/TestRedundantNullabilityCheck.java @@ -0,0 +1,17 @@ +package io.papermc.checkstyle.checks; + +import io.papermc.checkstyle.CheckTest; +import io.papermc.checkstyle.CheckTestBuilder; + +class TestRedundantNullabilityCheck { + + @CheckTest("testdata.RedundantNullability") + void test(final CheckTestBuilder builder) { + builder + .addViolation("10:8: Redundant NullMarked annotation") + .addViolation("14:8: Redundant NullMarked annotation") + .addViolation("18:8: Redundant NullMarked annotation") + .addViolation("22:8: Redundant NullMarked annotation") + .addCheck(new RedundantNullabilityCheck()); + } +} diff --git a/paper-checkstyle/src/testData/java/testdata/RedundantNullability.java b/paper-checkstyle/src/testData/java/testdata/RedundantNullability.java new file mode 100644 index 000000000000..0598bda5aa81 --- /dev/null +++ b/paper-checkstyle/src/testData/java/testdata/RedundantNullability.java @@ -0,0 +1,36 @@ +package testdata; + +import org.jspecify.annotations.NullMarked; + +public class RedundantNullability { + + @NullMarked + public static class OuterClass { + + @NullMarked + public static class RedundantInnerClass { + } + + @NullMarked + public interface RedundantInnerInterface { + } + + @NullMarked + public record RedundantInnerRecord() { + } + + @NullMarked + public enum RedundantInnerEnum { + } + + public static class ValidInnerClass { + } + } + + public static class NonAnnotatedOuter { + + @NullMarked + public static class ValidAnnotatedInner { + } + } +}