diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/utils/AnnotationUtil.java b/src/main/java/com/puppycrawl/tools/checkstyle/utils/AnnotationUtil.java index a79f6ccf197..ce41100976b 100644 --- a/src/main/java/com/puppycrawl/tools/checkstyle/utils/AnnotationUtil.java +++ b/src/main/java/com/puppycrawl/tools/checkstyle/utils/AnnotationUtil.java @@ -123,13 +123,8 @@ public static boolean containsAnnotation(DetailAST ast, Set annotations) if (!annotations.isEmpty()) { final DetailAST firstMatchingAnnotation = findFirstAnnotation(ast, annotationNode -> { - DetailAST identNode = annotationNode.findFirstToken(TokenTypes.IDENT); - if (identNode == null) { - identNode = annotationNode.findFirstToken(TokenTypes.DOT) - .findFirstToken(TokenTypes.IDENT); - } - - return annotations.contains(identNode.getText()); + final String annotationFullIdent = getAnnotationFullIdent(annotationNode); + return annotations.contains(annotationFullIdent); }); result = firstMatchingAnnotation != null; } @@ -137,6 +132,28 @@ public static boolean containsAnnotation(DetailAST ast, Set annotations) return result; } + /** + * Gets the full ident text of the annotation AST. + * + * @param annotationNode The annotation AST. + * @return The full ident text. + */ + private static String getAnnotationFullIdent(DetailAST annotationNode) { + final DetailAST identNode = annotationNode.findFirstToken(TokenTypes.IDENT); + final String annotationString; + + // If no `IDENT` is found, then we have a `DOT` -> more than 1 qualifier + if (identNode == null) { + final DetailAST dotNode = annotationNode.findFirstToken(TokenTypes.DOT); + annotationString = FullIdent.createFullIdent(dotNode).getText(); + } + else { + annotationString = identNode.getText(); + } + + return annotationString; + } + /** * Checks if the AST is annotated with {@code Override} or * {@code java.lang.Override} annotation. diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/checks/javadoc/MissingJavadocMethodCheckTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/checks/javadoc/MissingJavadocMethodCheckTest.java index 9442b579e71..53808b98d95 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/checks/javadoc/MissingJavadocMethodCheckTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/checks/javadoc/MissingJavadocMethodCheckTest.java @@ -82,7 +82,9 @@ public void newTest() throws Exception { @Test public void allowedAnnotationsTest() throws Exception { - final String[] expected = CommonUtil.EMPTY_STRING_ARRAY; + final String[] expected = { + "32:5: " + getCheckMessage(MSG_JAVADOC_MISSING), + }; verifyWithInlineConfigParser( getPath("InputMissingJavadocMethodAllowedAnnotations.java"), expected); } diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/checks/javadoc/MissingJavadocTypeCheckTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/checks/javadoc/MissingJavadocTypeCheckTest.java index aef7d1acb1e..4b594a18b66 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/checks/javadoc/MissingJavadocTypeCheckTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/checks/javadoc/MissingJavadocTypeCheckTest.java @@ -291,4 +291,75 @@ public void testInterfaceMemberScopeIsPublic() throws Exception { expected); } + @Test + public void testQualifiedAnnotation1() throws Exception { + final String[] expected = { + "16:5: " + getCheckMessage(MSG_JAVADOC_MISSING), + "20:5: " + getCheckMessage(MSG_JAVADOC_MISSING), + "23:5: " + getCheckMessage(MSG_JAVADOC_MISSING), + }; + verifyWithInlineConfigParser( + getPath("InputMissingJavadocTypeQualifiedAnnotation1.java"), expected); + } + + @Test + public void testQualifiedAnnotation2() throws Exception { + final String[] expected = { + "20:5: " + getCheckMessage(MSG_JAVADOC_MISSING), + "23:5: " + getCheckMessage(MSG_JAVADOC_MISSING), + }; + verifyWithInlineConfigParser( + getPath("InputMissingJavadocTypeQualifiedAnnotation2.java"), expected); + } + + @Test + public void testQualifiedAnnotation3() throws Exception { + final String[] expected = { + "16:5: " + getCheckMessage(MSG_JAVADOC_MISSING), + "22:5: " + getCheckMessage(MSG_JAVADOC_MISSING), + }; + verifyWithInlineConfigParser( + getPath("InputMissingJavadocTypeQualifiedAnnotation3.java"), expected); + } + + @Test + public void testQualifiedAnnotation4() throws Exception { + final String[] expected = { + "17:5: " + getCheckMessage(MSG_JAVADOC_MISSING), + "21:5: " + getCheckMessage(MSG_JAVADOC_MISSING), + }; + verifyWithInlineConfigParser( + getPath("InputMissingJavadocTypeQualifiedAnnotation4.java"), expected); + } + + @Test + public void testQualifiedAnnotation5() throws Exception { + final String[] expected = CommonUtil.EMPTY_STRING_ARRAY; + verifyWithInlineConfigParser( + getPath("InputMissingJavadocTypeQualifiedAnnotation5.java"), expected); + } + + @Test + public void testMultipleQualifiedAnnotation() throws Exception { + final String[] expected = { + "29:5: " + getCheckMessage(MSG_JAVADOC_MISSING), + "38:5: " + getCheckMessage(MSG_JAVADOC_MISSING), + }; + verifyWithInlineConfigParser( + getPath("InputMissingJavadocTypeMultipleQualifiedAnnotation.java"), expected); + } + + @Test + public void testQualifiedAnnotationWithParameters() throws Exception { + final String[] expected = { + "33:5: " + getCheckMessage(MSG_JAVADOC_MISSING), + "37:5: " + getCheckMessage(MSG_JAVADOC_MISSING), + "42:5: " + getCheckMessage(MSG_JAVADOC_MISSING), + "50:5: " + getCheckMessage(MSG_JAVADOC_MISSING), + }; + verifyWithInlineConfigParser( + getPath("InputMissingJavadocTypeQualifiedAnnotationWithParameters.java"), + expected); + } + } diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/utils/AnnotationUtilTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/utils/AnnotationUtilTest.java index 6f8ce1ab078..6c6f5cd98d2 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/utils/AnnotationUtilTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/utils/AnnotationUtilTest.java @@ -225,29 +225,6 @@ public void testContainsAnnotationListWithNoAnnotationNode() { .isFalse(); } - @Test - public void testContainsAnnotationListWithEmptyAnnotationNode() { - final DetailAstImpl ast = new DetailAstImpl(); - final DetailAstImpl modifiersAst = create( - TokenTypes.MODIFIERS, - create( - TokenTypes.ANNOTATION, - create( - TokenTypes.DOT, - create( - TokenTypes.IDENT, - "Override") - ) - ) - ); - ast.addChild(modifiersAst); - final Set annotations = Set.of("Override"); - final boolean result = AnnotationUtil.containsAnnotation(ast, annotations); - assertWithMessage("The dot-ident variation should also work") - .that(result) - .isTrue(); - } - @Test public void testContainsAnnotationListWithNoMatchingAnnotation() { final DetailAstImpl ast = new DetailAstImpl(); diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadocmethod/InputMissingJavadocMethodAllowedAnnotations.java b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadocmethod/InputMissingJavadocMethodAllowedAnnotations.java index cf1c5bdabc7..3ea76f10e73 100644 --- a/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadocmethod/InputMissingJavadocMethodAllowedAnnotations.java +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadocmethod/InputMissingJavadocMethodAllowedAnnotations.java @@ -28,6 +28,7 @@ public void allowed1() {} @ThisIsOkToo public void allowed2() {} + // violation below 'Missing a Javadoc comment.' @com.puppycrawl.tools.checkstyle.checks.javadoc.missingjavadocmethod.ThisIsOk public void allowed3() {} diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeMultipleQualifiedAnnotation.java b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeMultipleQualifiedAnnotation.java new file mode 100644 index 00000000000..7a88ae934b8 --- /dev/null +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeMultipleQualifiedAnnotation.java @@ -0,0 +1,47 @@ +/* +MissingJavadocType +scope = (default)public +excludeScope = (default)null +skipAnnotations = Ann1, AnnClass.Ann3 +tokens = INTERFACE_DEF + + +*/ + +package com.puppycrawl.tools.checkstyle.checks.javadoc.missingjavadoctype; + +@interface Ann1 { } +@interface Ann2 { } +@interface Ann3 { } + +class AnnClass { + public @interface Ann1 { } + public @interface Ann2 { } + public @interface Ann3 { } +} + +public class InputMissingJavadocTypeMultipleQualifiedAnnotation { + @Ann1 // ok + @Ann2 + @Ann3 + public interface A { } + + @Ann2 // violation 'Missing a Javadoc comment.' + @Ann3 + public interface B { } + + @Ann2 // ok + @Ann3 + @Ann1 + public interface C { } + + @AnnClass.Ann1 // violation 'Missing a Javadoc comment.' + @Ann2 + @Ann3 + public interface D { } + + @AnnClass.Ann2 // ok + @Ann2 + @AnnClass.Ann3 + public interface E { } +} diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeQualifiedAnnotation1.java b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeQualifiedAnnotation1.java new file mode 100644 index 00000000000..746c401eb59 --- /dev/null +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeQualifiedAnnotation1.java @@ -0,0 +1,26 @@ +/* +MissingJavadocType +scope = (default)public +excludeScope = (default)null +skipAnnotations = (default)Generated +tokens = INTERFACE_DEF + + +*/ + +package com.puppycrawl.tools.checkstyle.checks.javadoc.missingjavadoctype; + +public class InputMissingJavadocTypeQualifiedAnnotation1 { + public @interface SomeAnnotation { } + + @SomeAnnotation // violation 'Missing a Javadoc comment.' + public interface A { } + + // violation below 'Missing a Javadoc comment.' + @InputMissingJavadocTypeQualifiedAnnotation1.SomeAnnotation + public interface B { } + + @com.puppycrawl.tools.checkstyle.checks.javadoc // violation 'Missing a Javadoc comment.' + .missingjavadoctype.InputMissingJavadocTypeQualifiedAnnotation1.SomeAnnotation + public interface C { } +} diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeQualifiedAnnotation2.java b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeQualifiedAnnotation2.java new file mode 100644 index 00000000000..9e5b655b7c9 --- /dev/null +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeQualifiedAnnotation2.java @@ -0,0 +1,26 @@ +/* +MissingJavadocType +scope = (default)public +excludeScope = (default)null +skipAnnotations = SomeAnnotation +tokens = INTERFACE_DEF + + +*/ + +package com.puppycrawl.tools.checkstyle.checks.javadoc.missingjavadoctype; + +public class InputMissingJavadocTypeQualifiedAnnotation2 { + public @interface SomeAnnotation { } + + @SomeAnnotation // ok + public interface A { } + + // violation below 'Missing a Javadoc comment.' + @InputMissingJavadocTypeQualifiedAnnotation2.SomeAnnotation + public interface B { } + + @com.puppycrawl.tools.checkstyle.checks.javadoc // violation 'Missing a Javadoc comment.' + .missingjavadoctype.InputMissingJavadocTypeQualifiedAnnotation2.SomeAnnotation + public interface C { } +} diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeQualifiedAnnotation3.java b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeQualifiedAnnotation3.java new file mode 100644 index 00000000000..820f67a7fea --- /dev/null +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeQualifiedAnnotation3.java @@ -0,0 +1,25 @@ +/* +MissingJavadocType +scope = (default)public +excludeScope = (default)null +skipAnnotations = InputMissingJavadocTypeQualifiedAnnotation3.SomeAnnotation +tokens = INTERFACE_DEF + + +*/ + +package com.puppycrawl.tools.checkstyle.checks.javadoc.missingjavadoctype; + +public class InputMissingJavadocTypeQualifiedAnnotation3 { + public @interface SomeAnnotation { } + + @SomeAnnotation // violation 'Missing a Javadoc comment.' + public interface A { } + + @InputMissingJavadocTypeQualifiedAnnotation3.SomeAnnotation // ok + public interface B { } + + @com.puppycrawl.tools.checkstyle.checks.javadoc // violation 'Missing a Javadoc comment.' + .missingjavadoctype.InputMissingJavadocTypeQualifiedAnnotation3.SomeAnnotation + public interface C { } +} diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeQualifiedAnnotation4.java b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeQualifiedAnnotation4.java new file mode 100644 index 00000000000..7bb217baeaf --- /dev/null +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeQualifiedAnnotation4.java @@ -0,0 +1,27 @@ +/* +MissingJavadocType +scope = (default)public +excludeScope = (default)null +skipAnnotations = com.puppycrawl.tools.checkstyle.checks.javadoc.missingjavadoctype.\ + InputMissingJavadocTypeQualifiedAnnotation4.SomeAnnotation +tokens = INTERFACE_DEF + + +*/ + +package com.puppycrawl.tools.checkstyle.checks.javadoc.missingjavadoctype; + +public class InputMissingJavadocTypeQualifiedAnnotation4 { + public @interface SomeAnnotation { } + + @SomeAnnotation // violation 'Missing a Javadoc comment.' + public interface A { } + + // violation below 'Missing a Javadoc comment.' + @InputMissingJavadocTypeQualifiedAnnotation4.SomeAnnotation + public interface B { } + + @com.puppycrawl.tools.checkstyle.checks.javadoc.missingjavadoctype // ok + .InputMissingJavadocTypeQualifiedAnnotation4.SomeAnnotation + public interface C { } +} diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeQualifiedAnnotation5.java b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeQualifiedAnnotation5.java new file mode 100644 index 00000000000..275e3f63403 --- /dev/null +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeQualifiedAnnotation5.java @@ -0,0 +1,27 @@ +/* +MissingJavadocType +scope = (default)public +excludeScope = (default)null +skipAnnotations = SomeAnnotation, InputMissingJavadocTypeQualifiedAnnotation5.SomeAnnotation, \ + com.puppycrawl.tools.checkstyle.checks.javadoc.missingjavadoctype.\ + InputMissingJavadocTypeQualifiedAnnotation5.SomeAnnotation +tokens = INTERFACE_DEF + + +*/ + +package com.puppycrawl.tools.checkstyle.checks.javadoc.missingjavadoctype; + +public class InputMissingJavadocTypeQualifiedAnnotation5 { + public @interface SomeAnnotation { } + + @SomeAnnotation // ok + public interface A { } + + @InputMissingJavadocTypeQualifiedAnnotation5.SomeAnnotation // ok + public interface B { } + + @com.puppycrawl.tools.checkstyle.checks.javadoc.missingjavadoctype // ok + .InputMissingJavadocTypeQualifiedAnnotation5.SomeAnnotation + public interface C { } +} diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeQualifiedAnnotationWithParameters.java b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeQualifiedAnnotationWithParameters.java new file mode 100644 index 00000000000..7589e4ee46a --- /dev/null +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeQualifiedAnnotationWithParameters.java @@ -0,0 +1,56 @@ +/* +MissingJavadocType +scope = (default)public +excludeScope = (default)null +skipAnnotations = SomeAnnotation +tokens = INTERFACE_DEF + + +*/ + +package com.puppycrawl.tools.checkstyle.checks.javadoc.missingjavadoctype; + +public class InputMissingJavadocTypeQualifiedAnnotationWithParameters { + public @interface SomeAnnotation { + String value() default ""; + int quantity() default 1; + boolean isOk() default false; + } + + @SomeAnnotation("value") // ok + public interface A { } + + @SomeAnnotation(value = "value", quantity = 5, isOk = true) // ok + public interface B { } + + @SomeAnnotation( // ok + value = "value", + isOk = true + ) + public interface C { } + + // violation below 'Missing a Javadoc comment.' + @InputMissingJavadocTypeQualifiedAnnotationWithParameters.SomeAnnotation("value") + public interface D { } + + // violation below 'Missing a Javadoc comment.' + @InputMissingJavadocTypeQualifiedAnnotationWithParameters + .SomeAnnotation(value = "value", isOk = false) + public interface E { } + + // violation below 'Missing a Javadoc comment.' + @InputMissingJavadocTypeQualifiedAnnotationWithParameters.SomeAnnotation( + value = "value", + quantity = 2, + isOk = false + ) + public interface F { } + + // violation below 'Missing a Javadoc comment.' + @InputMissingJavadocTypeQualifiedAnnotationWithParameters + .SomeAnnotation( + value = "value", + isOk = false + ) + public interface G { } +}