public class CommentsIndentationCheck extends AbstractCheck
Controls the indentation between comments and surrounding code. Comments are indented at the same level as the surrounding code. Detailed info about such convention can be found here
tokens - tokens to check
Type is java.lang.String[].
Validation type is tokenSet.
Default value is:
SINGLE_LINE_COMMENT,
BLOCK_COMMENT_BEGIN.
Please take a look at the following examples to understand how the check works:
Example #1: Block comments.
1 /* 2 * it is Ok 3 */ 4 boolean bool = true; 5 6 /* violation 7 * (block comment should have the same indentation level as line 9) 8 */ 9 double d = 3.14;
Example #2: Comment is placed at the end of the block and has previous statement.
1 public void foo1() {
2 foo2();
3 // it is OK
4 }
5
6 public void foo2() {
7 foo3();
8 // violation (comment should have the same indentation level as line 7)
9 }
Example #3: Comment is used as a single line border to separate groups of methods.
1 /////////////////////////////// it is OK
2
3 public void foo7() {
4 int a = 0;
5 }
6
7 ///////////////////////////// violation (should have the same indentation level as line 9)
8
9 public void foo8() {}
Example #4: Comment has distributed previous statement.
1 public void foo11() {
2 CheckUtil
3 .getFirstNode(new DetailAST())
4 .getFirstChild()
5 .getNextSibling();
6 // it is OK
7 }
8
9 public void foo12() {
10 CheckUtil
11 .getFirstNode(new DetailAST())
12 .getFirstChild()
13 .getNextSibling();
14 // violation (should have the same indentation level as line 10)
15 }
Example #5: Single line block comment is placed within an empty code block. Note, if comment is placed at the end of the empty code block, we have Checkstyle's limitations to clearly detect user intention of explanation target - above or below. The only case we can assume as a violation is when a single line comment within the empty code block has indentation level that is lower than the indentation level of the closing right curly brace.
1 public void foo46() {
2 // comment
3 // block
4 // it is OK (we cannot clearly detect user intention of explanation target)
5 }
6
7 public void foo46() {
8 // comment
9 // block
10 // violation (comment should have the same indentation level as line 11)
11 }
Example #6: 'fallthrough' comments and similar.
0 switch(a) {
1 case "1":
2 int k = 7;
3 // it is OK
4 case "2":
5 int k = 7;
6 // it is OK
7 case "3":
8 if (true) {}
9 // violation (should have the same indentation level as line 8 or 10)
10 case "4":
11 case "5": {
12 int a;
13 }
14 // fall through (it is OK)
15 case "12": {
16 int a;
17 }
18 default:
19 // it is OK
20 }
Example #7: Comment is placed within a distributed statement.
1 String breaks = "J" 2 // violation (comment should have the same indentation level as line 3) 3 + "A" 4 // it is OK 5 + "V" 6 + "A" 7 // it is OK 8 ;
Example #8: Comment is placed within an empty case block. Note, if comment is placed at the end of the empty case block, we have Checkstyle's limitations to clearly detect user intention of explanation target - above or below. The only case we can assume as a violation is when a single line comment within the empty case block has indentation level that is lower than the indentation level of the next case token.
1 case 4: 2 // it is OK 3 case 5: 4 // violation (should have the same indentation level as line 3 or 5) 5 case 6:
Example #9: Single line block comment has previous and next statement.
1 String s1 = "Clean code!"; 2 s.toString().toString().toString(); 3 // single line 4 // block 5 // comment (it is OK) 6 int a = 5; 7 8 String s2 = "Code complete!"; 9 s.toString().toString().toString(); 10 // violation (should have the same indentation level as line 11) 11 // violation (should have the same indentation level as line 12) 12 // violation (should have the same indentation level as line 13) 13 int b = 18;
Example #10: Comment within the block tries to describe the next code block.
1 public void foo42() {
2 int a = 5;
3 if (a == 5) {
4 int b;
5 // it is OK
6 } else if (a ==6) { ... }
7 }
8
9 public void foo43() {
10 try {
11 int a;
12 // Why do we catch exception here? - violation (not the same indentation as line 11)
13 } catch (Exception e) { ... }
14 }
To configure the Check:
<module name="CommentsIndentation"/>
Parent is com.puppycrawl.tools.checkstyle.TreeWalker
Violation Message Keys:
comments.indentation.block
comments.indentation.single
AutomaticBean.OutputStreamOptions| Modifier and Type | Field and Description |
|---|---|
static java.lang.String |
MSG_KEY_BLOCK
A key is pointing to the warning message text in "messages.properties" file.
|
static java.lang.String |
MSG_KEY_SINGLE
A key is pointing to the warning message text in "messages.properties" file.
|
| Constructor and Description |
|---|
CommentsIndentationCheck() |
| Modifier and Type | Method and Description |
|---|---|
private static boolean |
areInSameMethodCallWithSameIndent(DetailAST comment)
Checks if the comment is inside a method call with same indentation of
first expression.
|
private boolean |
areSameLevelIndented(DetailAST comment,
DetailAST prevStmt,
DetailAST nextStmt)
Checks if comment and next code statement
(or previous code stmt like case in switch block) are indented at the same level,
e.g.:
|
private int |
countEmptyLines(DetailAST startStatement,
DetailAST endStatement)
Count the number of empty lines between statements.
|
private DetailAST |
findPreviousStatement(DetailAST comment,
DetailAST root)
Finds a previous statement of the comment.
|
private static DetailAST |
findStartTokenOfMethodCallChain(DetailAST root)
Finds the start token of method call chain.
|
private static DetailAST |
findTokenWhichBeginsTheLine(DetailAST root)
Finds a token which begins the line.
|
int[] |
getAcceptableTokens()
The configurable token set.
|
int[] |
getDefaultTokens()
Returns the default token a check is interested in.
|
private static DetailAST |
getDistributedPreviousStatement(DetailAST comment)
Returns the first token of the distributed previous statement of comment.
|
private static DetailAST |
getFirstExpressionNodeFromMethodCall(DetailAST methodCall)
Returns the first EXPR DetailAST child from parent of comment.
|
private int |
getLineStart(int lineNo)
Get a column number where a code starts.
|
private static java.lang.String |
getMessageKey(DetailAST comment)
Get a message key depending on a comment type.
|
private static DetailAST |
getNextStmt(DetailAST comment)
Returns the next statement of a comment.
|
private DetailAST |
getNextToken(DetailAST checkedStatement)
Get the token to start counting the number of lines to add to the distance aim from.
|
private DetailAST |
getOneLinePreviousStatement(DetailAST comment)
Does pre-order traverse of abstract syntax tree to find the previous statement of the
comment.
|
private static DetailAST |
getPrevCaseToken(DetailAST parentStatement)
Gets previous case-token for comment.
|
private DetailAST |
getPreviousStatement(DetailAST comment)
Returns the previous statement of a comment.
|
private static DetailAST |
getPrevStatementFromSwitchBlock(DetailAST comment)
Gets comment's previous statement from switch block.
|
private static DetailAST |
getPrevStatementWhenCommentIsUnderCase(DetailAST parentStatement)
Gets previous statement for comment which is placed immediately under case.
|
int[] |
getRequiredTokens()
The tokens that this check must be registered for.
|
private void |
handleCommentAtTheEndOfTheCodeBlock(DetailAST prevStmt,
DetailAST comment,
DetailAST nextStmt)
Handles a comment which is placed at the end of non empty code block.
|
private void |
handleCommentInEmptyCaseBlock(DetailAST prevStmt,
DetailAST comment,
DetailAST nextStmt)
Handles a comment which is placed within empty case block.
|
private void |
handleCommentInEmptyCodeBlock(DetailAST comment,
DetailAST nextStmt)
Handles a comment which is placed within the empty code block.
|
private void |
handleFallThroughComment(DetailAST prevStmt,
DetailAST comment,
DetailAST nextStmt)
Handles 'fall through' single line comment.
|
private static boolean |
isBlockStart(DetailAST root)
Whether the AST node starts a block.
|
private static boolean |
isComment(DetailAST ast)
Whether the ast is a comment.
|
private static boolean |
isCommentAtTheEndOfTheCodeBlock(DetailAST nextStmt)
Checks whether a comment is placed at the end of the code block.
|
private static boolean |
isCommentForMultiblock(DetailAST endBlockStmt)
Whether the comment might have been used for the next block in a multi-block structure.
|
boolean |
isCommentNodesRequired()
Whether comment nodes are required or not.
|
private static boolean |
isDefinition(DetailAST previousSibling)
Whether the statement is a kind of definition (method, class etc.).
|
private boolean |
isDistributedExpression(DetailAST comment)
Checks whether the previous statement of a comment is a method call chain or
string concatenation statement distributed over two ore more lines.
|
private boolean |
isDistributedPreviousStatement(DetailAST comment)
Checks whether the previous statement of a comment is distributed over two or more lines.
|
private static boolean |
isDistributedReturnStatement(DetailAST commentPreviousSibling)
Checks whether the previous statement of a comment is a distributed return statement.
|
private static boolean |
isDistributedThrowStatement(DetailAST commentPreviousSibling)
Checks whether the previous statement of a comment is a distributed throw statement.
|
private static boolean |
isFallThroughComment(DetailAST prevStmt,
DetailAST nextStmt)
Checks whether comment is a 'fall through' comment.
|
private static boolean |
isInEmptyCaseBlock(DetailAST prevStmt,
DetailAST nextStmt)
Checks whether case block is empty.
|
private static boolean |
isInEmptyCodeBlock(DetailAST prevStmt,
DetailAST nextStmt)
Checks whether comment is placed in the empty code block.
|
private boolean |
isOnPreviousLineIgnoringComments(DetailAST currentStatement,
DetailAST checkedStatement)
Checks whether the checked statement is on the previous line ignoring empty lines
and lines which contain only comments.
|
private static boolean |
isStatementWithPossibleCurlies(DetailAST previousSibling)
Whether the statement can have or always have curly brackets.
|
private boolean |
isTrailingBlockComment(DetailAST blockComment)
Checks if current comment block is trailing comment, e.g.:
|
private boolean |
isTrailingComment(DetailAST comment)
Checks if current comment is a trailing comment.
|
private boolean |
isTrailingSingleLineComment(DetailAST singleLineComment)
Checks if current single line comment is trailing comment, e.g.:
|
private static boolean |
isUsingOfObjectReferenceToInvokeMethod(DetailAST root)
Checks whether there is a use of an object reference to invoke an object's method on line.
|
private void |
logMultilineIndentation(DetailAST prevStmt,
DetailAST comment,
DetailAST nextStmt)
Logs comment which can have the same indentation level as next or previous statement.
|
private void |
visitComment(DetailAST comment)
Checks comment indentations over surrounding code, e.g.:
|
void |
visitToken(DetailAST commentAst)
Called to process a token.
|
beginTree, clearViolations, destroy, finishTree, getFileContents, getLine, getLineCodePoints, getLines, getTabWidth, getTokenNames, getViolations, init, leaveToken, log, log, log, setFileContents, setTabWidth, setTokensfinishLocalSetup, getCustomMessages, getId, getMessageBundle, getSeverity, getSeverityLevel, setId, setSeverityconfigure, contextualize, getConfiguration, setupChildpublic static final java.lang.String MSG_KEY_SINGLE
public static final java.lang.String MSG_KEY_BLOCK
public CommentsIndentationCheck()
public int[] getDefaultTokens()
AbstractCheckgetDefaultTokens in class AbstractCheckTokenTypespublic int[] getAcceptableTokens()
AbstractCheckgetAcceptableTokens in class AbstractCheckTokenTypespublic int[] getRequiredTokens()
AbstractCheckgetRequiredTokens in class AbstractCheckTokenTypespublic boolean isCommentNodesRequired()
AbstractCheckisCommentNodesRequired in class AbstractCheckpublic void visitToken(DetailAST commentAst)
AbstractCheckvisitToken in class AbstractCheckcommentAst - the token to processprivate void visitComment(DetailAST comment)
// some comment - this is ok
double d = 3.14;
// some comment - this is <b>not</b> ok.
double d1 = 5.0;
comment - comment to check.private static DetailAST getNextStmt(DetailAST comment)
comment - comment.private DetailAST getPreviousStatement(DetailAST comment)
comment - comment.private boolean isDistributedPreviousStatement(DetailAST comment)
comment - comment to check.private boolean isDistributedExpression(DetailAST comment)
comment - comment to check.private static boolean isStatementWithPossibleCurlies(DetailAST previousSibling)
previousSibling - the statement to check.private static boolean isDefinition(DetailAST previousSibling)
previousSibling - the statement to check.private static boolean isDistributedReturnStatement(DetailAST commentPreviousSibling)
commentPreviousSibling - previous sibling of the comment.private static boolean isDistributedThrowStatement(DetailAST commentPreviousSibling)
commentPreviousSibling - previous sibling of the comment.private static DetailAST getDistributedPreviousStatement(DetailAST comment)
comment - comment to check.private static boolean isInEmptyCaseBlock(DetailAST prevStmt, DetailAST nextStmt)
prevStmt - next statement.nextStmt - previous statement.private static boolean isFallThroughComment(DetailAST prevStmt, DetailAST nextStmt)
...
case OPTION_ONE:
int someVariable = 1;
// fall through
case OPTION_TWO:
int a = 5;
break;
...
prevStmt - previous statement.nextStmt - next statement.private static boolean isCommentAtTheEndOfTheCodeBlock(DetailAST nextStmt)
nextStmt - next statement.private static boolean isInEmptyCodeBlock(DetailAST prevStmt, DetailAST nextStmt)
...
// empty code block
...
prevStmt - previous statement.nextStmt - next statement.private void handleCommentInEmptyCaseBlock(DetailAST prevStmt, DetailAST comment, DetailAST nextStmt)
...
case OPTION_ONE:
// violation
case OPTION_TWO:
...
prevStmt - previous statement.comment - single line comment.nextStmt - next statement.private void handleFallThroughComment(DetailAST prevStmt, DetailAST comment, DetailAST nextStmt)
...
case OPTION_ONE:
int someVariable = 1;
// fall through - OK
case OPTION_TWO:
int a = 5;
break;
...
...
case OPTION_ONE:
int someVariable = 1;
// then init variable a - OK
case OPTION_TWO:
int a = 5;
break;
...
prevStmt - previous statement.comment - single line comment.nextStmt - next statement.private void handleCommentAtTheEndOfTheCodeBlock(DetailAST prevStmt, DetailAST comment, DetailAST nextStmt)
if (a == true) {
int b = 1;
// comment
}
prevStmt - previous statement.comment - comment to check.nextStmt - next statement.private static boolean isCommentForMultiblock(DetailAST endBlockStmt)
endBlockStmt - the end of the current block.private void handleCommentInEmptyCodeBlock(DetailAST comment, DetailAST nextStmt)
if (a == true) {
// violation
}
comment - comment to check.nextStmt - next statement.private DetailAST getOneLinePreviousStatement(DetailAST comment)
comment - current statement.private static boolean isComment(DetailAST ast)
ast - the ast to check.private static boolean isBlockStart(DetailAST root)
root - the AST node to check.private DetailAST findPreviousStatement(DetailAST comment, DetailAST root)
comment - comment.root - root token of the line.private static DetailAST findTokenWhichBeginsTheLine(DetailAST root)
root - root token of the line.private static boolean isUsingOfObjectReferenceToInvokeMethod(DetailAST root)
root - root token of the line.private static DetailAST findStartTokenOfMethodCallChain(DetailAST root)
root - root token of the line.private boolean isOnPreviousLineIgnoringComments(DetailAST currentStatement, DetailAST checkedStatement)
currentStatement - current statement.checkedStatement - checked statement.private DetailAST getNextToken(DetailAST checkedStatement)
checkedStatement - the checked statement.private int countEmptyLines(DetailAST startStatement, DetailAST endStatement)
startStatement - start statement.endStatement - end statement.private void logMultilineIndentation(DetailAST prevStmt, DetailAST comment, DetailAST nextStmt)
prevStmt - previous statement.comment - comment.nextStmt - next statement.private static java.lang.String getMessageKey(DetailAST comment)
comment - the comment to process.private static DetailAST getPrevStatementFromSwitchBlock(DetailAST comment)
comment - single-line comment.private static DetailAST getPrevStatementWhenCommentIsUnderCase(DetailAST parentStatement)
parentStatement - comment's parent statement.private static DetailAST getPrevCaseToken(DetailAST parentStatement)
parentStatement - comment's parent statement.private boolean areSameLevelIndented(DetailAST comment, DetailAST prevStmt, DetailAST nextStmt)
// some comment - same indentation level
int x = 10;
// some comment - different indentation level
int x1 = 5;
/*
*
*/
boolean bool = true; - same indentation level
comment - single line comment.prevStmt - previous code statement.nextStmt - next code statement.private int getLineStart(int lineNo)
lineNo - the line number to get column number in.private boolean isTrailingComment(DetailAST comment)
comment - comment to check.private boolean isTrailingSingleLineComment(DetailAST singleLineComment)
double d = 3.14; // some comment
singleLineComment - single line comment.private boolean isTrailingBlockComment(DetailAST blockComment)
double d = 3.14; /* some comment */
/* some comment */ double d = 18.5;
blockComment - block comment begin.private static boolean areInSameMethodCallWithSameIndent(DetailAST comment)
private final boolean myList = someMethod(
// Some comment here
s1,
s2,
s3
// ok
);
comment - comment to check.private static DetailAST getFirstExpressionNodeFromMethodCall(DetailAST methodCall)
methodCall - methodCall DetailAst from which node to be extracted.Copyright © 2001-2022. All Rights Reserved.