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..eb27b929d78 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,7 @@ 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()); + return doesAnnotationMatch(annotationNode, annotations); }); result = firstMatchingAnnotation != null; } @@ -137,6 +131,80 @@ public static boolean containsAnnotation(DetailAST ast, Set annotations) return result; } + /** + * Checks if annotation is found in the set of provided annotations. + * + * @param annotations A collection of annotations to look through. + * @param annotationNode Annotation to look for. + * @return {@code true} if the annotation is contained in the set. + */ + private static boolean doesAnnotationMatch(DetailAST annotationNode, Set annotations) { + 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 = convertAnnotationNameToString(dotNode); + } + else { + annotationString = identNode.getText(); + } + + boolean annotationsMatch = false; + + for (String annotation : annotations) { + if (annotation.equals(annotationString)) { + annotationsMatch = true; + break; + } + } + + return annotationsMatch; + } + + /** + * Converts (qualified) annotation name to string. + * + *

+ * For example: + *

+ *
+     * @org.example.MyAnn -> "org.example.MyAnn"
+     * @MyAnn -> "MyAnn"
+     * 
+ * + * @param rootDotNode The root DOT node of the (qualified) annotation. + * @return Annotation name as string. + */ + private static String convertAnnotationNameToString(DetailAST rootDotNode) { + final StringBuilder result = new StringBuilder(); + final StringBuilder temp = new StringBuilder(); + final char dot = '.'; + DetailAST currDotNode = rootDotNode; + + while (currDotNode != null) { + if (currDotNode.findFirstToken(TokenTypes.DOT) == null) { + temp.append(currDotNode.getFirstChild().getText()); + if (currDotNode.getChildCount() > 1) { + temp.append(dot); + temp.append(currDotNode.getLastChild().getText()); + } + } + else { + temp.append(currDotNode.findFirstToken(TokenTypes.IDENT).getText()); + } + if (result.length() != 0) { + temp.append(dot); + } + currDotNode = currDotNode.findFirstToken(TokenTypes.DOT); + result.insert(0, temp); + temp.setLength(0); + } + + return result.toString(); + } + /** * 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/MissingJavadocTypeCheckTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/checks/javadoc/MissingJavadocTypeCheckTest.java index aef7d1acb1e..ac9ac1015d5 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,45 @@ public void testInterfaceMemberScopeIsPublic() throws Exception { expected); } + @Test + public void testFullyQualifiedAnnotation1() throws Exception { + final String[] expected = { + "16:5: " + getCheckMessage(MSG_JAVADOC_MISSING), + "19:5: " + getCheckMessage(MSG_JAVADOC_MISSING), + "22:5: " + getCheckMessage(MSG_JAVADOC_MISSING), + }; + verifyWithInlineConfigParser( + getPath("InputMissingJavadocTypeFullyQualifiedAnnotation1.java"), expected); + } + + @Test + public void testFullyQualifiedAnnotation2() throws Exception { + final String[] expected = { + "19:5: " + getCheckMessage(MSG_JAVADOC_MISSING), + "22:5: " + getCheckMessage(MSG_JAVADOC_MISSING), + }; + verifyWithInlineConfigParser( + getPath("InputMissingJavadocTypeFullyQualifiedAnnotation2.java"), expected); + } + + @Test + public void testFullyQualifiedAnnotation3() throws Exception { + final String[] expected = { + "16:5: " + getCheckMessage(MSG_JAVADOC_MISSING), + "22:5: " + getCheckMessage(MSG_JAVADOC_MISSING), + }; + verifyWithInlineConfigParser( + getPath("InputMissingJavadocTypeFullyQualifiedAnnotation3.java"), expected); + } + + @Test + public void testFullyQualifiedAnnotation4() throws Exception { + final String[] expected = { + "17:5: " + getCheckMessage(MSG_JAVADOC_MISSING), + "20:5: " + getCheckMessage(MSG_JAVADOC_MISSING), + }; + verifyWithInlineConfigParser( + getPath("InputMissingJavadocTypeFullyQualifiedAnnotation4.java"), expected); + } + } 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..4a516828702 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,9 +28,6 @@ public void allowed1() {} @ThisIsOkToo public void allowed2() {} - @com.puppycrawl.tools.checkstyle.checks.javadoc.missingjavadocmethod.ThisIsOk - public void allowed3() {} - @Override public void method() {} } diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeFullyQualifiedAnnotation1.java b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeFullyQualifiedAnnotation1.java new file mode 100644 index 00000000000..0702aa81ee2 --- /dev/null +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeFullyQualifiedAnnotation1.java @@ -0,0 +1,25 @@ +/* +MissingJavadocType +scope = (default)public +excludeScope = (default)null +skipAnnotations = (default)Generated +tokens = INTERFACE_DEF + + +*/ + +package com.puppycrawl.tools.checkstyle.checks.javadoc.missingjavadoctype; + +public class InputMissingJavadocTypeFullyQualifiedAnnotation1 { + public @interface SomeAnnotation { } + + @SomeAnnotation // violation + public interface A { } + + @InputMissingJavadocTypeFullyQualifiedAnnotation1.SomeAnnotation // violation + public interface B { } + + @com.puppycrawl.tools.checkstyle.checks.javadoc.missingjavadoctype. // violation + InputMissingJavadocTypeFullyQualifiedAnnotation1.SomeAnnotation + public interface C { } +} diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeFullyQualifiedAnnotation2.java b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeFullyQualifiedAnnotation2.java new file mode 100644 index 00000000000..1c6abf2651a --- /dev/null +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeFullyQualifiedAnnotation2.java @@ -0,0 +1,25 @@ +/* +MissingJavadocType +scope = (default)public +excludeScope = (default)null +skipAnnotations = SomeAnnotation +tokens = INTERFACE_DEF + + +*/ + +package com.puppycrawl.tools.checkstyle.checks.javadoc.missingjavadoctype; + +public class InputMissingJavadocTypeFullyQualifiedAnnotation2 { + public @interface SomeAnnotation { } + + @SomeAnnotation // ok + public interface A { } + + @InputMissingJavadocTypeFullyQualifiedAnnotation2.SomeAnnotation // violation + public interface B { } + + @com.puppycrawl.tools.checkstyle.checks.javadoc.missingjavadoctype. // violation + InputMissingJavadocTypeFullyQualifiedAnnotation2.SomeAnnotation + public interface C { } +} diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeFullyQualifiedAnnotation3.java b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeFullyQualifiedAnnotation3.java new file mode 100644 index 00000000000..2c3811b0dc2 --- /dev/null +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeFullyQualifiedAnnotation3.java @@ -0,0 +1,25 @@ +/* +MissingJavadocType +scope = (default)public +excludeScope = (default)null +skipAnnotations = InputMissingJavadocTypeFullyQualifiedAnnotation3.SomeAnnotation +tokens = INTERFACE_DEF + + +*/ + +package com.puppycrawl.tools.checkstyle.checks.javadoc.missingjavadoctype; + +public class InputMissingJavadocTypeFullyQualifiedAnnotation3 { + public @interface SomeAnnotation { } + + @SomeAnnotation // violation + public interface A { } + + @InputMissingJavadocTypeFullyQualifiedAnnotation3.SomeAnnotation // ok + public interface B { } + + @com.puppycrawl.tools.checkstyle.checks.javadoc.missingjavadoctype. // violation + InputMissingJavadocTypeFullyQualifiedAnnotation3.SomeAnnotation + public interface C { } +} diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeFullyQualifiedAnnotation4.java b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeFullyQualifiedAnnotation4.java new file mode 100644 index 00000000000..cc207d75f7a --- /dev/null +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype/InputMissingJavadocTypeFullyQualifiedAnnotation4.java @@ -0,0 +1,26 @@ +/* +MissingJavadocType +scope = (default)public +excludeScope = (default)null +skipAnnotations = com.puppycrawl.tools.checkstyle.checks.javadoc.missingjavadoctype.\ + InputMissingJavadocTypeFullyQualifiedAnnotation4.SomeAnnotation +tokens = INTERFACE_DEF + + +*/ + +package com.puppycrawl.tools.checkstyle.checks.javadoc.missingjavadoctype; + +public class InputMissingJavadocTypeFullyQualifiedAnnotation4 { + public @interface SomeAnnotation { } + + @SomeAnnotation // violation + public interface A { } + + @InputMissingJavadocTypeFullyQualifiedAnnotation4.SomeAnnotation // violation + public interface B { } + + @com.puppycrawl.tools.checkstyle.checks.javadoc.missingjavadoctype. // ok + InputMissingJavadocTypeFullyQualifiedAnnotation4.SomeAnnotation + public interface C { } +}