Skip to content

Commit

Permalink
Issue checkstyle#10924: Checks that use getLine() should check code p…
Browse files Browse the repository at this point in the history
…oints for spaces
  • Loading branch information
MUzairS15 committed Dec 17, 2021
1 parent c9134ce commit f6d8b28
Show file tree
Hide file tree
Showing 26 changed files with 503 additions and 181 deletions.
Expand Up @@ -294,6 +294,16 @@ public final String getLine(int index) {
return context.get().fileContents.getLine(index);
}

/**
* Returns the line associated with the tree.
*
* @param index index of the line
* @return the array of Unicode code points
*/
public final int[] getLineCodePoints(int index) {
return getLine(index).codePoints().toArray();
}

/**
* The actual context holder.
*/
Expand Down
Expand Up @@ -31,6 +31,7 @@
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
import com.puppycrawl.tools.checkstyle.utils.CheckUtil;
import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
import com.puppycrawl.tools.checkstyle.utils.StringUtil;

/**
* <p>
Expand Down Expand Up @@ -431,8 +432,8 @@ private boolean hasTrailComment(DetailAST ast) {
final List<TextBlock> commentList = blockComments.get(lineNo);
if (commentList != null) {
final TextBlock comment = commentList.get(commentList.size() - 1);
final String line = getLines()[lineNo - 1];
result = isTrailingBlockComment(comment, line);
final int[] codePoints = getLineCodePoints(lineNo - 1);
result = isTrailingBlockComment(comment, codePoints);
}
}
return result;
Expand All @@ -442,12 +443,13 @@ private boolean hasTrailComment(DetailAST ast) {
* Whether the C style comment is trailing.
*
* @param comment the comment to check.
* @param line the line where the comment starts.
* @param codePoints The array of Unicode code points.
* @return true if the comment is trailing.
*/
private static boolean isTrailingBlockComment(TextBlock comment, String line) {
private static boolean isTrailingBlockComment(TextBlock comment, int...codePoints) {
return comment.getText().length != 1
|| CommonUtil.isBlank(line.substring(comment.getEndColNo() + 1));
|| CommonUtil.isBlank(StringUtil.subArray(codePoints,
comment.getEndColNo() + 1, codePoints.length));
}

/**
Expand Down
Expand Up @@ -26,6 +26,7 @@
import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
import com.puppycrawl.tools.checkstyle.utils.StringUtil;

/**
* <p>
Expand Down Expand Up @@ -290,41 +291,42 @@ private boolean hasText(final DetailAST slistAST) {
final int slistColNo = slistAST.getColumnNo();
final int rcurlyLineNo = rcurlyAST.getLineNo();
final int rcurlyColNo = rcurlyAST.getColumnNo();
final String[] lines = getLines();
boolean returnValue = false;
if (slistLineNo == rcurlyLineNo) {
// Handle braces on the same line
final String txt = lines[slistLineNo - 1]
.substring(slistColNo + 1, rcurlyColNo);
final int[] txt = StringUtil.subArray(getLineCodePoints(slistLineNo - 1),
slistColNo + 1, rcurlyColNo);

if (!CommonUtil.isBlank(txt)) {
returnValue = true;
}
}
else {
final String firstLine = lines[slistLineNo - 1].substring(slistColNo + 1);
final String lastLine = lines[rcurlyLineNo - 1].substring(0, rcurlyColNo);
int[] codePoints = getLineCodePoints(slistLineNo - 1);
final int[] firstLine = StringUtil.subArray(codePoints,
slistColNo + 1, codePoints.length);
codePoints = getLineCodePoints(rcurlyLineNo - 1);
final int[] lastLine = StringUtil.subArray(codePoints, 0, rcurlyColNo);
// check if all lines are also only whitespace
returnValue = !(CommonUtil.isBlank(firstLine) && CommonUtil.isBlank(lastLine))
|| !checkIsAllLinesAreWhitespace(lines, slistLineNo, rcurlyLineNo);
|| !checkIsAllLinesAreWhitespace(slistLineNo, rcurlyLineNo);
}
return returnValue;
}

/**
* Checks is all lines in array contain whitespaces only.
*
* @param lines
* array of lines
* @param lineFrom
* check from this line number
* @param lineTo
* check to this line numbers
* @return true if lines contain only whitespaces
*/
private static boolean checkIsAllLinesAreWhitespace(String[] lines, int lineFrom, int lineTo) {
private boolean checkIsAllLinesAreWhitespace(int lineFrom, int lineTo) {
boolean result = true;
for (int i = lineFrom; i < lineTo - 1; i++) {
if (!CommonUtil.isBlank(lines[i])) {
if (!CommonUtil.isBlank(getLineCodePoints(i))) {
result = false;
break;
}
Expand Down
Expand Up @@ -442,21 +442,21 @@ private static DetailAST findLastAnnotation(DetailAST modifiers) {
*/
private void verifyBrace(final DetailAST brace,
final DetailAST startToken) {
final String braceLine = getLine(brace.getLineNo() - 1);
final int[] codePoints = getLineCodePoints(brace.getLineNo() - 1);

// Check for being told to ignore, or have '{}' which is a special case
if (braceLine.length() <= brace.getColumnNo() + 1
|| braceLine.charAt(brace.getColumnNo() + 1) != '}') {
if (codePoints.length <= brace.getColumnNo() + 1
|| codePoints[brace.getColumnNo() + 1] != '}') {
if (option == LeftCurlyOption.NL) {
if (!CommonUtil.hasWhitespaceBefore(brace.getColumnNo(), braceLine)) {
if (!CommonUtil.hasWhitespaceBefore(codePoints, brace.getColumnNo())) {
log(brace, MSG_KEY_LINE_NEW, OPEN_CURLY_BRACE, brace.getColumnNo() + 1);
}
}
else if (option == LeftCurlyOption.EOL) {
validateEol(brace, braceLine);
validateEol(codePoints, brace);
}
else if (!TokenUtil.areOnSameLine(startToken, brace)) {
validateNewLinePosition(brace, startToken, braceLine);
validateNewLinePosition(codePoints, brace, startToken);
}
}
}
Expand All @@ -465,10 +465,10 @@ else if (!TokenUtil.areOnSameLine(startToken, brace)) {
* Validate EOL case.
*
* @param brace brace AST
* @param braceLine line content
* @param codePoints the array of Unicode code points
*/
private void validateEol(DetailAST brace, String braceLine) {
if (CommonUtil.hasWhitespaceBefore(brace.getColumnNo(), braceLine)) {
private void validateEol(int[] codePoints, DetailAST brace) {
if (CommonUtil.hasWhitespaceBefore(codePoints, brace.getColumnNo())) {
log(brace, MSG_KEY_LINE_PREVIOUS, OPEN_CURLY_BRACE, brace.getColumnNo() + 1);
}
if (!hasLineBreakAfter(brace)) {
Expand All @@ -481,19 +481,19 @@ private void validateEol(DetailAST brace, String braceLine) {
*
* @param brace brace AST
* @param startToken start Token
* @param braceLine content of line with Brace
* @param codePoints the array of Unicode code points
*/
private void validateNewLinePosition(DetailAST brace, DetailAST startToken, String braceLine) {
private void validateNewLinePosition(int[] codePoints, DetailAST brace, DetailAST startToken) {
// not on the same line
if (startToken.getLineNo() + 1 == brace.getLineNo()) {
if (CommonUtil.hasWhitespaceBefore(brace.getColumnNo(), braceLine)) {
if (CommonUtil.hasWhitespaceBefore(codePoints, brace.getColumnNo())) {
log(brace, MSG_KEY_LINE_PREVIOUS, OPEN_CURLY_BRACE, brace.getColumnNo() + 1);
}
else {
log(brace, MSG_KEY_LINE_NEW, OPEN_CURLY_BRACE, brace.getColumnNo() + 1);
}
}
else if (!CommonUtil.hasWhitespaceBefore(brace.getColumnNo(), braceLine)) {
else if (!CommonUtil.hasWhitespaceBefore(codePoints, brace.getColumnNo())) {
log(brace, MSG_KEY_LINE_NEW, OPEN_CURLY_BRACE, brace.getColumnNo() + 1);
}
}
Expand Down
Expand Up @@ -328,7 +328,8 @@ private String validate(Details details) {
else if (shouldBeOnSameLine(option, details)) {
violation = MSG_KEY_LINE_SAME;
}
else if (shouldBeAloneOnLine(option, details, getLine(details.rcurly.getLineNo() - 1))) {
else if (shouldBeAloneOnLine(option, details,
getLineCodePoints(details.rcurly.getLineNo() - 1))) {
violation = MSG_KEY_LINE_ALONE;
}
return violation;
Expand Down Expand Up @@ -365,60 +366,59 @@ private static boolean shouldBeOnSameLine(RightCurlyOption bracePolicy, Details
* Checks that a right curly should be alone on a line.
*
* @param bracePolicy option for placing the right curly brace
* @param codePoints the array of Unicode code points
* @param details Details for validation
* @param targetSrcLine A string with contents of rcurly's line
* @return true if a right curly should be alone on a line.
*/
private static boolean shouldBeAloneOnLine(RightCurlyOption bracePolicy,
Details details,
String targetSrcLine) {
int...codePoints) {
return bracePolicy == RightCurlyOption.ALONE
&& shouldBeAloneOnLineWithAloneOption(details, targetSrcLine)
&& shouldBeAloneOnLineWithAloneOption(codePoints, details)
|| (bracePolicy == RightCurlyOption.ALONE_OR_SINGLELINE
|| details.shouldCheckLastRcurly)
&& shouldBeAloneOnLineWithNotAloneOption(details, targetSrcLine);
&& shouldBeAloneOnLineWithNotAloneOption(codePoints, details);
}

/**
* Whether right curly should be alone on line when ALONE option is used.
*
* @param details details for validation.
* @param targetSrcLine A string with contents of rcurly's line
* @param codePoints the array of Unicode code points
* @return true, if right curly should be alone on line when ALONE option is used.
*/
private static boolean shouldBeAloneOnLineWithAloneOption(Details details,
String targetSrcLine) {
return !isAloneOnLine(details, targetSrcLine);
private static boolean shouldBeAloneOnLineWithAloneOption(int[] codePoints,
Details details) {
return !isAloneOnLine(codePoints, details);
}

/**
* Whether right curly should be alone on line when ALONE_OR_SINGLELINE or SAME option is used.
*
* @param details details for validation.
* @param targetSrcLine A string with contents of rcurly's line
* @param codePoints the array of Unicode code points
* @return true, if right curly should be alone on line
* when ALONE_OR_SINGLELINE or SAME option is used.
*/
private static boolean shouldBeAloneOnLineWithNotAloneOption(Details details,
String targetSrcLine) {
return shouldBeAloneOnLineWithAloneOption(details, targetSrcLine)
private static boolean shouldBeAloneOnLineWithNotAloneOption(int[] codePoints,
Details details) {
return shouldBeAloneOnLineWithAloneOption(codePoints, details)
&& !isBlockAloneOnSingleLine(details);
}

/**
* Checks whether right curly is alone on a line.
*
* @param details for validation.
* @param targetSrcLine A string with contents of rcurly's line
* @param codePoints the array of Unicode code points
* @return true if right curly is alone on a line.
*/
private static boolean isAloneOnLine(Details details, String targetSrcLine) {
private static boolean isAloneOnLine(int[] codePoints, Details details) {
final DetailAST rcurly = details.rcurly;
final DetailAST nextToken = details.nextToken;
return (nextToken == null || !TokenUtil.areOnSameLine(rcurly, nextToken)
|| skipDoubleBraceInstInit(details))
&& CommonUtil.hasWhitespaceBefore(details.rcurly.getColumnNo(),
targetSrcLine);
&& CommonUtil.hasWhitespaceBefore(codePoints, details.rcurly.getColumnNo());
}

/**
Expand Down
Expand Up @@ -496,7 +496,7 @@ private boolean hasFallThroughComment(DetailAST currentCase, DetailAST nextCase)
// }
final int startLineNo = currentCase.getLineNo();
for (int i = endLineNo - 2; i > startLineNo - 1; i--) {
if (!CommonUtil.isBlank(lines[i])) {
if (!CommonUtil.isBlank(getLineCodePoints(i))) {
allThroughComment = matchesComment(reliefPattern, lines[i], i + 1);
break;
}
Expand Down
Expand Up @@ -1180,11 +1180,11 @@ private static int compareImports(String import1, String import2) {
*/
private int getCountOfEmptyLinesBetween(int fromLineNo, int toLineNo) {
int result = 0;
final String[] lines = getLines();

for (int i = fromLineNo + 1; i <= toLineNo - 1; i++) {
final int[] codePoints = getLineCodePoints(i - 1);
// "- 1" because the numbering is one-based
if (CommonUtil.isBlank(lines[i - 1])) {
if (CommonUtil.isBlank(codePoints)) {
result++;
}
}
Expand Down
Expand Up @@ -21,6 +21,7 @@

import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
import com.puppycrawl.tools.checkstyle.utils.CommonUtil;

/**
* Handler for annotation array initialization blocks.
Expand Down Expand Up @@ -131,10 +132,10 @@ protected IndentLevel getChildrenExpectedIndent() {
*/
private int getNextFirstNonBlankOnLineAfter(int lineNo, int columnNo) {
int realColumnNo = columnNo + 1;
final String line = getIndentCheck().getLines()[lineNo - 1];
final int lineLength = line.length();
final int[] codePoints = getIndentCheck().getLineCodePoints(lineNo - 1);
final int lineLength = codePoints.length;
while (realColumnNo < lineLength
&& Character.isWhitespace(line.charAt(realColumnNo))) {
&& CommonUtil.isCodePointWhitespace(codePoints, realColumnNo)) {
realColumnNo++;
}

Expand Down
Expand Up @@ -21,6 +21,7 @@

import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
import com.puppycrawl.tools.checkstyle.utils.CommonUtil;

/**
* Handler for array initialization blocks.
Expand Down Expand Up @@ -135,10 +136,10 @@ protected IndentLevel getChildrenExpectedIndent() {
*/
private int getNextFirstNonBlankOnLineAfter(int lineNo, int columnNo) {
int realColumnNo = columnNo + 1;
final String line = getIndentCheck().getLines()[lineNo - 1];
final int lineLength = line.length();
final int[] codePoints = getIndentCheck().getLineCodePoints(lineNo - 1);
final int lineLength = codePoints.length;
while (realColumnNo < lineLength
&& Character.isWhitespace(line.charAt(realColumnNo))) {
&& CommonUtil.isCodePointWhitespace(codePoints, realColumnNo)) {
realColumnNo++;
}

Expand Down
Expand Up @@ -954,10 +954,10 @@ private DetailAST getNextToken(DetailAST checkedStatement) {
*/
private int countEmptyLines(DetailAST startStatement, DetailAST endStatement) {
int emptyLinesNumber = 0;
final String[] lines = getLines();
final int endLineNo = endStatement.getLineNo();
for (int lineNo = startStatement.getLineNo(); lineNo < endLineNo; lineNo++) {
if (CommonUtil.isBlank(lines[lineNo])) {
final int[] codePoints = getLineCodePoints(lineNo);
if (CommonUtil.isBlank(codePoints)) {
emptyLinesNumber++;
}
}
Expand Down Expand Up @@ -1108,9 +1108,9 @@ private boolean areSameLevelIndented(DetailAST comment, DetailAST prevStmt,
* @return the column number where a code starts.
*/
private int getLineStart(int lineNo) {
final char[] line = getLines()[lineNo - 1].toCharArray();
final int[] codePoints = getLineCodePoints(lineNo - 1);
int lineStart = 0;
while (Character.isWhitespace(line[lineStart])) {
while (CommonUtil.isCodePointWhitespace(codePoints, lineStart)) {
lineStart++;
}
return lineStart;
Expand Down Expand Up @@ -1145,9 +1145,9 @@ private boolean isTrailingComment(DetailAST comment) {
* @return true if current single line comment is trailing comment.
*/
private boolean isTrailingSingleLineComment(DetailAST singleLineComment) {
final String targetSourceLine = getLine(singleLineComment.getLineNo() - 1);
final int[] codePoints = getLineCodePoints(singleLineComment.getLineNo() - 1);
final int commentColumnNo = singleLineComment.getColumnNo();
return !CommonUtil.hasWhitespaceBefore(commentColumnNo, targetSourceLine);
return !CommonUtil.hasWhitespaceBefore(codePoints, commentColumnNo);
}

/**
Expand All @@ -1163,10 +1163,10 @@ private boolean isTrailingSingleLineComment(DetailAST singleLineComment) {
* @return true if current comment block is trailing comment.
*/
private boolean isTrailingBlockComment(DetailAST blockComment) {
final String commentLine = getLine(blockComment.getLineNo() - 1);
final int[] codePoints = getLineCodePoints(blockComment.getLineNo() - 1);
final int commentColumnNo = blockComment.getColumnNo();
final DetailAST nextSibling = blockComment.getNextSibling();
return !CommonUtil.hasWhitespaceBefore(commentColumnNo, commentLine)
return !CommonUtil.hasWhitespaceBefore(codePoints, commentColumnNo)
|| nextSibling != null && TokenUtil.areOnSameLine(nextSibling, blockComment);
}

Expand Down

0 comments on commit f6d8b28

Please sign in to comment.