forked from checkstyle/checkstyle
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Issue checkstyle#6723: new check: LeadingAsteriskAlignCheck
- Loading branch information
Showing
36 changed files
with
1,229 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
235 changes: 235 additions & 0 deletions
235
...java/com/puppycrawl/tools/checkstyle/checks/javadoc/JavadocLeadingAsteriskAlignCheck.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,235 @@ | ||
/////////////////////////////////////////////////////////////////////////////////////////////// | ||
// checkstyle: Checks Java source code and other text files for adherence to a set of rules. | ||
// Copyright (C) 2001-2024 the original author or authors. | ||
// | ||
// This library is free software; you can redistribute it and/or | ||
// modify it under the terms of the GNU Lesser General Public | ||
// License as published by the Free Software Foundation; either | ||
// version 2.1 of the License, or (at your option) any later version. | ||
// | ||
// This library is distributed in the hope that it will be useful, | ||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
// Lesser General Public License for more details. | ||
// | ||
// You should have received a copy of the GNU Lesser General Public | ||
// License along with this library; if not, write to the Free Software | ||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
/////////////////////////////////////////////////////////////////////////////////////////////// | ||
|
||
package com.puppycrawl.tools.checkstyle.checks.javadoc; | ||
|
||
import java.util.Optional; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
|
||
import com.puppycrawl.tools.checkstyle.GlobalStatefulCheck; | ||
import com.puppycrawl.tools.checkstyle.api.DetailAST; | ||
import com.puppycrawl.tools.checkstyle.api.DetailNode; | ||
import com.puppycrawl.tools.checkstyle.api.JavadocTokenTypes; | ||
import com.puppycrawl.tools.checkstyle.utils.CommonUtil; | ||
|
||
/** | ||
* <p> | ||
* Checks the alignment of | ||
* <a href="https://docs.oracle.com/en/java/javase/14/docs/specs/javadoc/doc-comment-spec.html#leading-asterisks"> | ||
* leading asterisks</a> in a Javadoc comment. The Check ensures that leading asterisks | ||
* are aligned vertically under the first asterisk ( * ) | ||
* of opening Javadoc tag. The alignment of closing Javadoc tag ( */ ) is also checked. | ||
* If a closing Javadoc tag contains non-whitespace character before it | ||
* then it's alignment will be ignored. | ||
* If the ending javadoc line contains a leading asterisk, then that leading asterisk's alignment | ||
* will be considered, the closing Javadoc tag will be ignored. | ||
* </p> | ||
* <p> | ||
* If you're using tabs then specify the the tab width in the | ||
* <a href="https://checkstyle.org/config.html#tabWidth">tabWidth</a> property. | ||
* </p> | ||
* <ul> | ||
* <li> | ||
* Property {@code violateExecutionOnNonTightHtml} - Control when to print violations if the | ||
* Javadoc being examined by this check violates the tight html rules defined at | ||
* <a href="https://checkstyle.org/writingjavadocchecks.html#Tight-HTML_rules">Tight-HTML Rules</a>. | ||
* Type is {@code boolean}. | ||
* Default value is {@code false}. | ||
* </li> | ||
* </ul> | ||
* <p> | ||
* Parent is {@code com.puppycrawl.tools.checkstyle.TreeWalker} | ||
* </p> | ||
* <p> | ||
* Violation Message Keys: | ||
* </p> | ||
* <ul> | ||
* <li> | ||
* {@code javadoc.asterisk.indentation} | ||
* </li> | ||
* <li> | ||
* {@code javadoc.missed.html.close} | ||
* </li> | ||
* <li> | ||
* {@code javadoc.parse.rule.error} | ||
* </li> | ||
* <li> | ||
* {@code javadoc.unclosedHtml} | ||
* </li> | ||
* <li> | ||
* {@code javadoc.wrong.singleton.html.tag} | ||
* </li> | ||
* </ul> | ||
* | ||
* @since 10.18.0 | ||
*/ | ||
@GlobalStatefulCheck | ||
public class JavadocLeadingAsteriskAlignCheck extends AbstractJavadocCheck { | ||
|
||
/** | ||
* A key is pointing to the warning message text in "messages.properties" | ||
* file. | ||
*/ | ||
public static final String MSG_KEY = "javadoc.asterisk.indentation"; | ||
|
||
/** Specifies the line number of starting block of the javadoc comment. */ | ||
private int javadocStartLineNumber; | ||
|
||
/** Specifies the column number of starting block of the javadoc comment with tabs expanded. */ | ||
private int expectedColumnNumberTabsExpanded; | ||
|
||
/** | ||
* Specifies the column number of the leading asterisk | ||
* without tabs expanded. | ||
*/ | ||
private int expectedColumnNumberWithoutExpandedTabs; | ||
|
||
/** Specifies the lines of the file being processed. */ | ||
private String[] fileLines; | ||
|
||
@Override | ||
public int[] getDefaultJavadocTokens() { | ||
return new int[] { | ||
JavadocTokenTypes.LEADING_ASTERISK, | ||
}; | ||
} | ||
|
||
@Override | ||
public int[] getRequiredJavadocTokens() { | ||
return getAcceptableJavadocTokens(); | ||
} | ||
|
||
@Override | ||
public void beginJavadocTree(DetailNode rootAst) { | ||
// this method processes and sets information of starting javadoc tag. | ||
fileLines = getLines(); | ||
final String startLine = fileLines[rootAst.getLineNumber() - 1]; | ||
javadocStartLineNumber = rootAst.getLineNumber(); | ||
expectedColumnNumberTabsExpanded = CommonUtil.lengthExpandedTabs( | ||
startLine, rootAst.getColumnNumber() - 1, getTabWidth()); | ||
} | ||
|
||
@Override | ||
public void visitJavadocToken(DetailNode ast) { | ||
// this method checks the alignment of leading asterisks. | ||
final boolean isJavadocStartingLine = ast.getLineNumber() == javadocStartLineNumber; | ||
|
||
if (!isJavadocStartingLine) { | ||
final Optional<Integer> leadingAsteriskColumnNumber = | ||
getAsteriskColumnNumber(ast.getText()); | ||
|
||
leadingAsteriskColumnNumber | ||
.map(columnNumber -> expandedTabs(ast.getText(), columnNumber)) | ||
.filter(columnNumber -> { | ||
return !hasValidAlignment(expectedColumnNumberTabsExpanded, columnNumber); | ||
}) | ||
.ifPresent(columnNumber -> { | ||
logViolation(ast.getLineNumber(), | ||
columnNumber, | ||
expectedColumnNumberTabsExpanded); | ||
}); | ||
} | ||
} | ||
|
||
@Override | ||
public void finishJavadocTree(DetailNode rootAst) { | ||
// this method checks the alignment of closing javadoc tag. | ||
final DetailAST javadocEndToken = getBlockCommentAst().getLastChild(); | ||
final String lastLine = fileLines[javadocEndToken.getLineNo() - 1]; | ||
final Optional<Integer> endingBlockColumnNumber = getAsteriskColumnNumber(lastLine); | ||
|
||
endingBlockColumnNumber | ||
.map(columnNumber -> expandedTabs(lastLine, columnNumber)) | ||
.filter(columnNumber -> { | ||
return !hasValidAlignment(expectedColumnNumberTabsExpanded, columnNumber); | ||
}) | ||
.ifPresent(columnNumber -> { | ||
logViolation(javadocEndToken.getLineNo(), | ||
columnNumber, | ||
expectedColumnNumberTabsExpanded); | ||
}); | ||
} | ||
|
||
/** | ||
* Processes and returns the column number of | ||
* leading asterisk with tabs expanded. | ||
* Also sets 'expectedColumnNumberWithoutExpandedTabs' if the leading asterisk is present. | ||
* | ||
* @param line javadoc comment line | ||
* @param columnNumber column number of leading asterisk | ||
* @return column number of leading asterisk with tabs expanded | ||
*/ | ||
private int expandedTabs(String line, int columnNumber) { | ||
expectedColumnNumberWithoutExpandedTabs = columnNumber - 1; | ||
return CommonUtil.lengthExpandedTabs( | ||
line, columnNumber, getTabWidth()); | ||
} | ||
|
||
/** | ||
* Processes and returns an OptionalInt containing | ||
* the column number of leading asterisk without tabs expanded. | ||
* | ||
* @param line javadoc comment line | ||
* @return asterisk's column number | ||
*/ | ||
private static Optional<Integer> getAsteriskColumnNumber(String line) { | ||
final Pattern pattern = Pattern.compile("^(\\s*)\\*"); | ||
final Matcher matcher = pattern.matcher(line); | ||
|
||
// We may not always have a leading asterisk because a javadoc line can start with | ||
// a non-whitespace character or the javadoc line can be empty. | ||
// In such cases, there is no leading asterisk and Optional will be empty. | ||
return Optional.of(matcher) | ||
.filter(Matcher::find) | ||
.map(matcherInstance -> matcherInstance.group(1)) | ||
.map(groupLength -> groupLength.length() + 1); | ||
} | ||
|
||
/** | ||
* Checks alignment of asterisks and logs violations. | ||
* | ||
* @param lineNumber line number of current comment line | ||
* @param asteriskColNumber column number of leading asterisk | ||
* @param expectedColNumber column number of javadoc starting token | ||
*/ | ||
private void logViolation(int lineNumber, | ||
int asteriskColNumber, | ||
int expectedColNumber) { | ||
|
||
log(lineNumber, | ||
expectedColumnNumberWithoutExpandedTabs, | ||
MSG_KEY, | ||
asteriskColNumber, | ||
expectedColNumber); | ||
} | ||
|
||
/** | ||
* Checks the column difference between | ||
* expected column number and leading asterisk column number. | ||
* | ||
* @param expectedColNumber column number of javadoc starting token | ||
* @param asteriskColNumber column number of leading asterisk | ||
* @return true if the asterisk is aligned properly, false otherwise | ||
*/ | ||
private static boolean hasValidAlignment(int expectedColNumber, | ||
int asteriskColNumber) { | ||
return expectedColNumber - asteriskColNumber == 0; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
src/main/resources/com/puppycrawl/tools/checkstyle/checks/javadoc/messages.properties
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.