From ad585631576a49b45b2f1802c7197cc57bf2a504 Mon Sep 17 00:00:00 2001
From: rnveach
Date: Sun, 23 Oct 2016 08:47:47 -0400
Subject: [PATCH] Issue #2427: added customizable javadoc tokens
---
.../checkstyle/api/JavadocTokenTypes.java | 3 +
.../checks/javadoc/AbstractJavadocCheck.java | 104 +++++++++++--
.../checks/javadoc/AtclauseOrderCheck.java | 5 +
.../checks/javadoc/JavadocParagraphCheck.java | 5 +
...avadocTagContinuationIndentationCheck.java | 5 +
.../javadoc/SingleLineJavadocCheck.java | 5 +
.../checks/javadoc/SummaryJavadocCheck.java | 5 +
.../javadoc/AbstractJavadocCheckTest.java | 142 ++++++++++++++++++
.../tools/checkstyle/internal/CheckUtil.java | 39 +++++
.../checkstyle/internal/XDocsPagesTest.java | 110 +++++++++++---
.../checkstyle/checks/javadoc/InputMain.java | 4 +
src/xdocs/config_javadoc.xml | 27 ++++
src/xdocs/writingjavadocchecks.xml.vm | 38 ++++-
13 files changed, 456 insertions(+), 36 deletions(-)
create mode 100644 src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/InputMain.java
diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/api/JavadocTokenTypes.java b/src/main/java/com/puppycrawl/tools/checkstyle/api/JavadocTokenTypes.java
index c09a67b0b29..624cff82d74 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/api/JavadocTokenTypes.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/api/JavadocTokenTypes.java
@@ -24,6 +24,9 @@
import com.puppycrawl.tools.checkstyle.grammars.javadoc.JavadocParser;
/**
+ * Contains the constants for all the tokens contained in the Abstract
+ * Syntax Tree for the javadoc grammar.
+ *
* @author Baratali Izmailov
* @see
* javadoc - The Java API Documentation Generator
diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.java
index faed34a1817..3ca4ab1f6e7 100755
--- a/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.java
@@ -19,9 +19,12 @@
package com.puppycrawl.tools.checkstyle.checks.javadoc;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Locale;
import java.util.Map;
-import java.util.stream.IntStream;
+import java.util.Set;
import com.puppycrawl.tools.checkstyle.JavadocDetailNodeParser;
import com.puppycrawl.tools.checkstyle.JavadocDetailNodeParser.ParseErrorMessage;
@@ -32,6 +35,7 @@
import com.puppycrawl.tools.checkstyle.api.JavadocTokenTypes;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
import com.puppycrawl.tools.checkstyle.utils.BlockCommentPosition;
+import com.puppycrawl.tools.checkstyle.utils.CommonUtils;
import com.puppycrawl.tools.checkstyle.utils.JavadocUtils;
/**
@@ -39,7 +43,6 @@
* @author Baratali Izmailov
*/
public abstract class AbstractJavadocCheck extends AbstractCheck {
-
/**
* Message key of error message. Missed close HTML tag breaks structure
* of parse tree, so parser stops parsing and generates such error
@@ -90,6 +93,9 @@ protected Map initialValue() {
*/
private final JavadocDetailNodeParser parser = new JavadocDetailNodeParser();
+ /** The javadoc tokens the check is interested in. */
+ private final Set javadocTokens = new HashSet<>();
+
/**
* DetailAST node of considered Javadoc comment that is just a block comment
* in Java language syntax tree.
@@ -97,8 +103,8 @@ protected Map initialValue() {
private DetailAST blockCommentAst;
/**
- * Returns the default token types a check is interested in.
- * @return the default token types
+ * Returns the default javadoc token types a check is interested in.
+ * @return the default javadoc token types
* @see JavadocTokenTypes
*/
public abstract int[] getDefaultJavadocTokens();
@@ -110,6 +116,84 @@ protected Map initialValue() {
*/
public abstract void visitJavadocToken(DetailNode ast);
+ /**
+ * The configurable javadoc token set.
+ * Used to protect Checks against malicious users who specify an
+ * unacceptable javadoc token set in the configuration file.
+ * The default implementation returns the check's default javadoc tokens.
+ * @return the javadoc token set this check is designed for.
+ * @see JavadocTokenTypes
+ */
+ public int[] getAcceptableJavadocTokens() {
+ final int[] defaultJavadocTokens = getDefaultJavadocTokens();
+ final int[] copy = new int[defaultJavadocTokens.length];
+ System.arraycopy(defaultJavadocTokens, 0, copy, 0, defaultJavadocTokens.length);
+ return copy;
+ }
+
+ /**
+ * The javadoc tokens that this check must be registered for.
+ * @return the javadoc token set this must be registered for.
+ * @see JavadocTokenTypes
+ */
+ public int[] getRequiredJavadocTokens() {
+ return CommonUtils.EMPTY_INT_ARRAY;
+ }
+
+ /**
+ * Adds a set of tokens the check is interested in.
+ * @param strRep the string representation of the tokens interested in
+ */
+ public final void setJavadocTokens(String... strRep) {
+ javadocTokens.clear();
+ for (String str : strRep) {
+ javadocTokens.add(JavadocUtils.getTokenId(str));
+ }
+ }
+
+ @Override
+ public void init() {
+ validateDefaultJavadocTokens();
+ if (javadocTokens.isEmpty()) {
+ for (int id : getDefaultJavadocTokens()) {
+ javadocTokens.add(id);
+ }
+ }
+ else {
+ final int[] acceptableJavadocTokens = getAcceptableJavadocTokens();
+ Arrays.sort(acceptableJavadocTokens);
+ for (Integer javadocTokenId : javadocTokens) {
+ if (Arrays.binarySearch(acceptableJavadocTokens, javadocTokenId) < 0) {
+ final String message = String.format(Locale.ROOT, "Javadoc Token \"%s\" was "
+ + "not found in Acceptable javadoc tokens list in check %s",
+ JavadocUtils.getTokenName(javadocTokenId), getClass().getName());
+ throw new IllegalStateException(message);
+ }
+ }
+ }
+ }
+
+ /**
+ * Validates that check's required javadoc tokens are subset of default javadoc tokens.
+ * @throws IllegalStateException when validation of default javadoc tokens fails
+ */
+ private void validateDefaultJavadocTokens() {
+ if (getRequiredJavadocTokens().length != 0) {
+ final int[] defaultJavadocTokens = getDefaultJavadocTokens();
+ Arrays.sort(defaultJavadocTokens);
+ for (final int javadocToken : getRequiredJavadocTokens()) {
+ if (Arrays.binarySearch(defaultJavadocTokens, javadocToken) < 0) {
+ final String message = String.format(Locale.ROOT,
+ "Javadoc Token \"%s\" from required javadoc "
+ + "tokens was not found in default "
+ + "javadoc tokens list in check %s",
+ javadocToken, getClass().getName());
+ throw new IllegalStateException(message);
+ }
+ }
+ }
+ }
+
/**
* Called before the starting to process a tree.
* @param rootAst
@@ -246,11 +330,9 @@ private void processTree(DetailNode root) {
* the root of tree for process
*/
private void walk(DetailNode root) {
- final int[] defaultTokenTypes = getDefaultJavadocTokens();
-
DetailNode curNode = root;
while (curNode != null) {
- final boolean waitsForProcessing = shouldBeProcessed(defaultTokenTypes, curNode);
+ boolean waitsForProcessing = shouldBeProcessed(curNode);
if (waitsForProcessing) {
visitJavadocToken(curNode);
@@ -265,6 +347,9 @@ private void walk(DetailNode root) {
toVisit = JavadocUtils.getNextSibling(curNode);
if (toVisit == null) {
curNode = curNode.getParent();
+ if (curNode != null) {
+ waitsForProcessing = shouldBeProcessed(curNode);
+ }
}
}
curNode = toVisit;
@@ -273,12 +358,11 @@ private void walk(DetailNode root) {
/**
* Checks whether the current node should be processed by the check.
- * @param defaultTokenTypes default token types.
* @param curNode current node.
* @return true if the current node should be processed by the check.
*/
- private boolean shouldBeProcessed(int[] defaultTokenTypes, DetailNode curNode) {
- return IntStream.of(defaultTokenTypes).anyMatch(i -> i == curNode.getType());
+ private boolean shouldBeProcessed(DetailNode curNode) {
+ return javadocTokens.contains(curNode.getType());
}
}
diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/AtclauseOrderCheck.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/AtclauseOrderCheck.java
index 6becb4cd16e..70c7141282d 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/AtclauseOrderCheck.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/AtclauseOrderCheck.java
@@ -130,6 +130,11 @@ public int[] getDefaultJavadocTokens() {
};
}
+ @Override
+ public int[] getRequiredJavadocTokens() {
+ return getAcceptableJavadocTokens();
+ }
+
@Override
public int[] getAcceptableTokens() {
return new int[] {TokenTypes.BLOCK_COMMENT_BEGIN};
diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/JavadocParagraphCheck.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/JavadocParagraphCheck.java
index 5c3c1ba39b7..d77cef83ff0 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/JavadocParagraphCheck.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/JavadocParagraphCheck.java
@@ -119,6 +119,11 @@ public int[] getDefaultJavadocTokens() {
};
}
+ @Override
+ public int[] getRequiredJavadocTokens() {
+ return getAcceptableJavadocTokens();
+ }
+
@Override
public int[] getAcceptableTokens() {
return new int[] {TokenTypes.BLOCK_COMMENT_BEGIN};
diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/JavadocTagContinuationIndentationCheck.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/JavadocTagContinuationIndentationCheck.java
index 4a9140f6609..2e7b7998fd9 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/JavadocTagContinuationIndentationCheck.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/JavadocTagContinuationIndentationCheck.java
@@ -72,6 +72,11 @@ public int[] getDefaultJavadocTokens() {
return new int[] {JavadocTokenTypes.DESCRIPTION };
}
+ @Override
+ public int[] getRequiredJavadocTokens() {
+ return getAcceptableJavadocTokens();
+ }
+
@Override
public int[] getAcceptableTokens() {
return new int[] {TokenTypes.BLOCK_COMMENT_BEGIN };
diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/SingleLineJavadocCheck.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/SingleLineJavadocCheck.java
index 744ae108295..1a314c1372c 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/SingleLineJavadocCheck.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/SingleLineJavadocCheck.java
@@ -100,6 +100,11 @@ public int[] getDefaultJavadocTokens() {
};
}
+ @Override
+ public int[] getRequiredJavadocTokens() {
+ return getAcceptableJavadocTokens();
+ }
+
@Override
public int[] getAcceptableTokens() {
return new int[] {TokenTypes.BLOCK_COMMENT_BEGIN };
diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/SummaryJavadocCheck.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/SummaryJavadocCheck.java
index 05549818e86..c2414530728 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/SummaryJavadocCheck.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/javadoc/SummaryJavadocCheck.java
@@ -116,6 +116,11 @@ public int[] getDefaultJavadocTokens() {
};
}
+ @Override
+ public int[] getRequiredJavadocTokens() {
+ return getAcceptableJavadocTokens();
+ }
+
@Override
public int[] getAcceptableTokens() {
return new int[] {TokenTypes.BLOCK_COMMENT_BEGIN };
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheckTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheckTest.java
index b2ae65b8837..5aa22d41e88 100644
--- a/src/test/java/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheckTest.java
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheckTest.java
@@ -33,7 +33,9 @@
import java.util.Map;
import org.junit.Assert;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
import com.puppycrawl.tools.checkstyle.BaseCheckTestSupport;
import com.puppycrawl.tools.checkstyle.Checker;
@@ -47,6 +49,9 @@
import com.puppycrawl.tools.checkstyle.utils.CommonUtils;
public class AbstractJavadocCheckTest extends BaseCheckTestSupport {
+ @Rule
+ public final TemporaryFolder temporaryFolder = new TemporaryFolder();
+
@Override
protected String getPath(String filename) throws IOException {
return super.getPath("checks" + File.separator
@@ -166,6 +171,64 @@ public void testBlockCommentPositionHasPrivateConstr() throws Exception {
TestUtils.assertUtilsClassHasPrivateConstructor(BlockCommentPosition.class);
}
+ @Test
+ public void testAcceptableTokensFail()
+ throws Exception {
+ final DefaultConfiguration checkConfig =
+ createCheckConfig(TokenIsNotInAcceptablesJavadocCheck.class);
+ checkConfig.addAttribute("javadocTokens", "RETURN_LITERAL");
+ try {
+ final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
+ verify(checkConfig, getPath("InputMain.java"), expected);
+ Assert.fail("CheckstyleException is expected");
+ }
+ catch (IllegalStateException ex) {
+ Assert.assertTrue(ex.getMessage().startsWith("Javadoc Token "
+ + "\"RETURN_LITERAL\" was not found in "
+ + "Acceptable javadoc tokens list in check"));
+ }
+ }
+
+ @Test
+ public void testAcceptableTokensPass()
+ throws Exception {
+ final DefaultConfiguration checkConfig =
+ createCheckConfig(TokenIsNotInAcceptablesJavadocCheck.class);
+ checkConfig.addAttribute("javadocTokens", "DEPRECATED_LITERAL");
+
+ final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
+ verify(checkConfig, getPath("InputMain.java"), expected);
+ }
+
+ @Test
+ public void testRequiredTokenIsNotInDefaultTokens() throws Exception {
+ final DefaultConfiguration checkConfig =
+ createCheckConfig(RequiredTokenIsNotInDefaultsJavadocCheck.class);
+ final String pathToEmptyFile = temporaryFolder.newFile("file.java").getPath();
+
+ try {
+ final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
+ verify(checkConfig, pathToEmptyFile, expected);
+ Assert.fail("CheckstyleException is expected");
+ }
+ catch (IllegalStateException ex) {
+ Assert.assertTrue(ex.getMessage().startsWith("Javadoc Token \""
+ + JavadocTokenTypes.RETURN_LITERAL + "\" from required"
+ + " javadoc tokens was not found in default javadoc tokens list in check"));
+ }
+ }
+
+ @Test
+ public void testVisitLeaveToken()
+ throws Exception {
+ JavadocVisitLeaveCheck.clearCounter();
+ final DefaultConfiguration checkConfig = createCheckConfig(JavadocVisitLeaveCheck.class);
+ final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
+ verify(checkConfig, getPath("InputJavadocPosition.java"), expected);
+ Assert.assertTrue(JavadocVisitLeaveCheck.visitCount > 0);
+ Assert.assertEquals(JavadocVisitLeaveCheck.visitCount, JavadocVisitLeaveCheck.leaveCount);
+ }
+
private static class TempCheck extends AbstractJavadocCheck {
@Override
@@ -217,4 +280,83 @@ public void visitJavadocToken(DetailNode ast) {
javadocsNumber++;
}
}
+
+ private static class RequiredTokenIsNotInDefaultsJavadocCheck extends AbstractJavadocCheck {
+ @Override
+ public int[] getRequiredJavadocTokens() {
+ return new int[] {JavadocTokenTypes.RETURN_LITERAL};
+ }
+
+ @Override
+ public int[] getDefaultJavadocTokens() {
+ return new int[] {JavadocTokenTypes.DEPRECATED_LITERAL};
+ }
+
+ @Override
+ public int[] getAcceptableJavadocTokens() {
+ return CommonUtils.EMPTY_INT_ARRAY;
+ }
+
+ @Override
+ public void visitJavadocToken(DetailNode ast) {
+ // not used
+ }
+ }
+
+ private static class TokenIsNotInAcceptablesJavadocCheck extends AbstractJavadocCheck {
+ @Override
+ public int[] getRequiredJavadocTokens() {
+ return new int[] {JavadocTokenTypes.DEPRECATED_LITERAL};
+ }
+
+ @Override
+ public int[] getDefaultJavadocTokens() {
+ return new int[] {JavadocTokenTypes.DEPRECATED_LITERAL};
+ }
+
+ @Override
+ public int[] getAcceptableJavadocTokens() {
+ return new int[] {JavadocTokenTypes.DEPRECATED_LITERAL};
+ }
+
+ @Override
+ public void visitJavadocToken(DetailNode ast) {
+ // not used
+ }
+ }
+
+ private static class JavadocVisitLeaveCheck extends AbstractJavadocCheck {
+ private static int visitCount;
+ private static int leaveCount;
+
+ static void clearCounter() {
+ visitCount = 0;
+ leaveCount = 0;
+ }
+
+ @Override
+ public int[] getRequiredJavadocTokens() {
+ return new int[] {JavadocTokenTypes.CHAR};
+ }
+
+ @Override
+ public int[] getDefaultJavadocTokens() {
+ return getRequiredJavadocTokens();
+ }
+
+ @Override
+ public int[] getAcceptableJavadocTokens() {
+ return getRequiredJavadocTokens();
+ }
+
+ @Override
+ public void visitJavadocToken(DetailNode ast) {
+ visitCount++;
+ }
+
+ @Override
+ public void leaveJavadocToken(DetailNode ast) {
+ leaveCount++;
+ }
+ }
}
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/internal/CheckUtil.java b/src/test/java/com/puppycrawl/tools/checkstyle/internal/CheckUtil.java
index a1971a7f0ab..d680c364631 100644
--- a/src/test/java/com/puppycrawl/tools/checkstyle/internal/CheckUtil.java
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/internal/CheckUtil.java
@@ -46,6 +46,7 @@
import com.puppycrawl.tools.checkstyle.checks.regexp.RegexpMultilineCheck;
import com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineCheck;
import com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck;
+import com.puppycrawl.tools.checkstyle.utils.JavadocUtils;
import com.puppycrawl.tools.checkstyle.utils.TokenUtils;
public final class CheckUtil {
@@ -335,4 +336,42 @@ public static String getTokenText(int[] tokens, int... subtractions) {
return result.toString();
}
}
+
+ public static String getJavadocTokenText(int[] tokens, int... subtractions) {
+ final StringBuilder result = new StringBuilder();
+ boolean first = true;
+
+ for (int token : tokens) {
+ boolean found = false;
+
+ for (int subtraction : subtractions) {
+ if (subtraction == token) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found) {
+ continue;
+ }
+
+ if (first) {
+ first = false;
+ }
+ else {
+ result.append(", ");
+ }
+
+ result.append(JavadocUtils.getTokenName(token));
+ }
+
+ if (result.length() == 0) {
+ result.append("empty");
+ }
+ else {
+ result.append(".");
+ }
+
+ return result.toString();
+ }
}
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/internal/XDocsPagesTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/internal/XDocsPagesTest.java
index ae4493c6f3a..3b763e4f698 100644
--- a/src/test/java/com/puppycrawl/tools/checkstyle/internal/XDocsPagesTest.java
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/internal/XDocsPagesTest.java
@@ -59,6 +59,7 @@
import com.puppycrawl.tools.checkstyle.api.AbstractFileSetCheck;
import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
import com.puppycrawl.tools.checkstyle.api.Configuration;
+import com.puppycrawl.tools.checkstyle.checks.javadoc.AbstractJavadocCheck;
public class XDocsPagesTest {
private static final Path JAVA_SOURCES_DIRECTORY = Paths.get("src/main/java");
@@ -112,6 +113,8 @@ public class XDocsPagesTest {
);
private static final Set CHECK_PROPERTIES = getProperties(AbstractCheck.class);
+ private static final Set JAVADOC_CHECK_PROPERTIES =
+ getProperties(AbstractJavadocCheck.class);
private static final Set FILESET_PROPERTIES = getProperties(AbstractFileSetCheck.class);
private static final List UNDOCUMENTED_PROPERTIES = Arrays.asList(
@@ -395,9 +398,30 @@ private static void validatePropertySection(String fileName, String sectionName,
final Set properties = getProperties(instance.getClass());
final Class> clss = instance.getClass();
+ fixCapturedProperties(sectionName, instance, clss, properties);
+
+ if (subSection != null) {
+ Assert.assertTrue(fileName + " section '" + sectionName
+ + "' should have no properties to show", !properties.isEmpty());
+
+ validatePropertySectionProperties(fileName, sectionName, subSection, instance,
+ properties);
+ }
+
+ Assert.assertTrue(fileName + " section '" + sectionName + "' should show properties: "
+ + properties, properties.isEmpty());
+ }
+
+ private static void fixCapturedProperties(String sectionName, Object instance, Class> clss,
+ Set properties) {
// remove global properties that don't need documentation
if (hasParentModule(sectionName)) {
- properties.removeAll(CHECK_PROPERTIES);
+ if (AbstractJavadocCheck.class.isAssignableFrom(clss)) {
+ properties.removeAll(JAVADOC_CHECK_PROPERTIES);
+ }
+ else if (AbstractCheck.class.isAssignableFrom(clss)) {
+ properties.removeAll(CHECK_PROPERTIES);
+ }
}
else if (AbstractFileSetCheck.class.isAssignableFrom(clss)) {
properties.removeAll(FILESET_PROPERTIES);
@@ -427,21 +451,27 @@ else if (AbstractFileSetCheck.class.isAssignableFrom(clss)) {
}
}
- if (subSection != null) {
- Assert.assertTrue(fileName + " section '" + sectionName
- + "' should have no properties to show", !properties.isEmpty());
+ if (AbstractJavadocCheck.class.isAssignableFrom(clss)) {
+ final AbstractJavadocCheck check = (AbstractJavadocCheck) instance;
- validatePropertySectionProperties(fileName, sectionName, subSection, instance,
- properties);
- }
+ final int[] acceptableJavadocTokens = check.getAcceptableJavadocTokens();
+ Arrays.sort(acceptableJavadocTokens);
+ final int[] defaultJavadocTokens = check.getDefaultJavadocTokens();
+ Arrays.sort(defaultJavadocTokens);
+ final int[] requiredJavadocTokens = check.getRequiredJavadocTokens();
+ Arrays.sort(requiredJavadocTokens);
- Assert.assertTrue(fileName + " section '" + sectionName + "' should show properties: "
- + properties, properties.isEmpty());
+ if (!Arrays.equals(acceptableJavadocTokens, defaultJavadocTokens)
+ || !Arrays.equals(acceptableJavadocTokens, requiredJavadocTokens)) {
+ properties.add("javadocTokens");
+ }
+ }
}
private static void validatePropertySectionProperties(String fileName, String sectionName,
Node subSection, Object instance, Set properties) throws Exception {
boolean skip = true;
+ boolean didJavadocTokens = false;
boolean didTokens = false;
for (Node row : XmlUtil.getChildrenElements(XmlUtil.getFirstChildElement(subSection))) {
@@ -461,25 +491,18 @@ private static void validatePropertySectionProperties(String fileName, String se
if ("tokens".equals(propertyName)) {
final AbstractCheck check = (AbstractCheck) instance;
-
- Assert.assertEquals(fileName + " section '" + sectionName
- + "' should have the basic token description", "tokens to check", columns
- .get(1).getTextContent());
- Assert.assertEquals(
- fileName + " section '" + sectionName
- + "' should have all the acceptable tokens",
- "subset of tokens "
- + CheckUtil.getTokenText(check.getAcceptableTokens(),
- check.getRequiredTokens()), columns.get(2).getTextContent()
- .replaceAll("\\s+", " ").trim());
- Assert.assertEquals(
- fileName + " section '" + sectionName
- + "' should have all the default tokens",
- CheckUtil.getTokenText(check.getDefaultTokens(), check.getRequiredTokens()),
- columns.get(3).getTextContent().replaceAll("\\s+", " ").trim());
+ validatePropertySectionPropertyTokens(fileName, sectionName, check, columns);
didTokens = true;
}
+ else if ("javadocTokens".equals(propertyName)) {
+ final AbstractJavadocCheck check = (AbstractJavadocCheck) instance;
+ validatePropertySectionPropertyJavadocTokens(fileName, sectionName, check, columns);
+ didJavadocTokens = true;
+ }
else {
+ Assert.assertFalse(fileName + " section '" + sectionName
+ + "' should have javadoc token properties next to last, before tokens",
+ didJavadocTokens);
Assert.assertFalse(fileName + " section '" + sectionName
+ "' should have a description for " + propertyName, columns.get(1)
.getTextContent().trim().isEmpty());
@@ -514,6 +537,43 @@ private static void validatePropertySectionProperties(String fileName, String se
}
}
+ private static void validatePropertySectionPropertyTokens(String fileName, String sectionName,
+ AbstractCheck check, List columns) {
+ Assert.assertEquals(fileName + " section '" + sectionName
+ + "' should have the basic token description", "tokens to check", columns.get(1)
+ .getTextContent());
+ Assert.assertEquals(
+ fileName + " section '" + sectionName + "' should have all the acceptable tokens",
+ "subset of tokens "
+ + CheckUtil.getTokenText(check.getAcceptableTokens(),
+ check.getRequiredTokens()), columns.get(2).getTextContent()
+ .replaceAll("\\s+", " ").trim());
+ Assert.assertEquals(fileName + " section '" + sectionName
+ + "' should have all the default tokens",
+ CheckUtil.getTokenText(check.getDefaultTokens(), check.getRequiredTokens()),
+ columns.get(3).getTextContent().replaceAll("\\s+", " ").trim());
+ }
+
+ private static void validatePropertySectionPropertyJavadocTokens(String fileName,
+ String sectionName, AbstractJavadocCheck check, List columns) {
+ Assert.assertEquals(fileName + " section '" + sectionName
+ + "' should have the basic token javadoc description", "javadoc tokens to check",
+ columns.get(1).getTextContent());
+ Assert.assertEquals(
+ fileName + " section '" + sectionName
+ + "' should have all the acceptable javadoc tokens",
+ "subset of javadoc tokens "
+ + CheckUtil.getJavadocTokenText(check.getAcceptableJavadocTokens(),
+ check.getRequiredJavadocTokens()), columns.get(2).getTextContent()
+ .replaceAll("\\s+", " ").trim());
+ Assert.assertEquals(
+ fileName + " section '" + sectionName
+ + "' should have all the default javadoc tokens",
+ CheckUtil.getJavadocTokenText(check.getDefaultJavadocTokens(),
+ check.getRequiredJavadocTokens()), columns.get(3).getTextContent()
+ .replaceAll("\\s+", " ").trim());
+ }
+
private static String getCheckPropertyExpectedTypeName(Class> clss, Object instance,
String propertyName) {
final String instanceName = instance.getClass().getSimpleName();
diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/InputMain.java b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/InputMain.java
new file mode 100644
index 00000000000..75c76701230
--- /dev/null
+++ b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/InputMain.java
@@ -0,0 +1,4 @@
+package com.puppycrawl.tools.checkstyle.checks.javadoc;
+/** Javadoc */
+public class InputMain {
+}
diff --git a/src/xdocs/config_javadoc.xml b/src/xdocs/config_javadoc.xml
index 125e2d160c4..da4b62cfe6c 100644
--- a/src/xdocs/config_javadoc.xml
+++ b/src/xdocs/config_javadoc.xml
@@ -1372,6 +1372,33 @@ public boolean isSomething()
+
+
+
+
Default configuration that will check @param
, @return
,
diff --git a/src/xdocs/writingjavadocchecks.xml.vm b/src/xdocs/writingjavadocchecks.xml.vm
index b6757caabf3..5ae02874661 100644
--- a/src/xdocs/writingjavadocchecks.xml.vm
+++ b/src/xdocs/writingjavadocchecks.xml.vm
@@ -532,7 +532,43 @@ JAVADOC ->
First
\r\n Second
[0:0]
- Not implemented yet. See Github Issue #2427.
+
+ There are four methods in AbstractJavadocCheck class to control the processed
+ JavadocTokenTypes -
+ one setter
+
+ setTokens(), which is used to define a custom set (which is different
+ from the default one) of the processed JavadocTokenTypes via config file and
+ three getters, which have to be overridden:
+
+ getDefaultJavadocTokens(),
+
+ getAcceptableJavadocTokens(),
+
+ getRequiredJavadocTokens().
+
+
+
+
+ -
+ getDefaultJavadocTokens() - returns a set of JavadocTokenTypes which are processed in
+
+ visitToken() method by default.
+
+
+ -
+ getRequiredJavadocTokens() - returns a set of JavadocTokenTypes which Check must be subscribed to for
+ a valid execution. If the user wants to specify a custom set of JavadocTokenTypes then
+ this set must contain all the JavadocTokenTypes from RequiredJavadocTokens.
+
+
+ -
+ getAcceptableJavadocTokens() - returns a set, which contains all the JavadocTokenTypes that
+ can be processed by the check. Both DefaultJavadocTokens and RequiredJavadocTokens and any custom
+ set of JavadocTokenTypes are subsets of AcceptableJavadocTokens.
+
+
+