Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #2427: added customizable javadoc tokens #3512

Merged
merged 1 commit into from
Nov 1, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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 <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/unix/javadoc.html">
* javadoc - The Java API Documentation Generator</a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -32,14 +35,14 @@
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;

/**
* Base class for Checks that process Javadoc comments.
* @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
Expand Down Expand Up @@ -90,15 +93,18 @@ protected Map<String, ParseStatus> initialValue() {
*/
private final JavadocDetailNodeParser parser = new JavadocDetailNodeParser();

/** The javadoc tokens the check is interested in. */
private final Set<Integer> javadocTokens = new HashSet<>();

/**
* DetailAST node of considered Javadoc comment that is just a block comment
* in Java language syntax tree.
*/
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();
Expand All @@ -110,6 +116,84 @@ protected Map<String, ParseStatus> 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
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand All @@ -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());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ public int[] getDefaultJavadocTokens() {
};
}

@Override
public int[] getRequiredJavadocTokens() {
return getAcceptableJavadocTokens();
}

@Override
public int[] getAcceptableTokens() {
return new int[] {TokenTypes.BLOCK_COMMENT_BEGIN};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ public int[] getDefaultJavadocTokens() {
};
}

@Override
public int[] getRequiredJavadocTokens() {
return getAcceptableJavadocTokens();
}

@Override
public int[] getAcceptableTokens() {
return new int[] {TokenTypes.BLOCK_COMMENT_BEGIN};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ public int[] getDefaultJavadocTokens() {
};
}

@Override
public int[] getRequiredJavadocTokens() {
return getAcceptableJavadocTokens();
}

@Override
public int[] getAcceptableTokens() {
return new int[] {TokenTypes.BLOCK_COMMENT_BEGIN };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@ public int[] getDefaultJavadocTokens() {
};
}

@Override
public int[] getRequiredJavadocTokens() {
return getAcceptableJavadocTokens();
}

@Override
public int[] getAcceptableTokens() {
return new int[] {TokenTypes.BLOCK_COMMENT_BEGIN };
Expand Down
Loading