Skip to content

Commit

Permalink
Issue #10924: Update SingleSpaceSeparatorCheck to use code points
Browse files Browse the repository at this point in the history
  • Loading branch information
MUzairS15 authored and romani committed Mar 22, 2022
1 parent d6bf623 commit d9f7a85
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 28 deletions.
3 changes: 3 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3292,6 +3292,9 @@
<param>
com.puppycrawl.tools.checkstyle.checks.AvoidEscapedUnicodeCharactersCheckTest
</param>
<param>
com.puppycrawl.tools.checkstyle.checks.whitespace.SingleSpaceSeparatorCheckTest
</param>
<!-- 2% mutation in ScopeUtil -->
<param>
com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocStyleCheckTest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@

package com.puppycrawl.tools.checkstyle.checks.whitespace;

import java.util.Arrays;

import com.puppycrawl.tools.checkstyle.StatelessCheck;
import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.utils.CodePointUtil;
import com.puppycrawl.tools.checkstyle.utils.CommonUtil;

/**
Expand Down Expand Up @@ -188,7 +191,7 @@ private void visitEachToken(DetailAST node) {

if (columnNo >= minSecondWhitespaceColumnNo
&& !isTextSeparatedCorrectlyFromPrevious(
getLine(currentNode.getLineNo() - 1),
getLineCodePoints(currentNode.getLineNo() - 1),
columnNo)) {
log(currentNode, MSG_KEY);
}
Expand Down Expand Up @@ -218,14 +221,14 @@ private void visitEachToken(DetailAST node) {
* end of a block comment. </li>
* </ul>
*
* @param line The line in the file to examine.
* @param line Unicode code point array of line in the file to examine.
* @param columnNo The column position in the {@code line} to examine.
* @return {@code true} if the text at {@code columnNo} is separated
* correctly from the previous token.
*/
private boolean isTextSeparatedCorrectlyFromPrevious(String line, int columnNo) {
private boolean isTextSeparatedCorrectlyFromPrevious(int[] line, int columnNo) {
return isSingleSpace(line, columnNo)
|| !isWhitespace(line, columnNo)
|| !CommonUtil.isCodePointWhitespace(line, columnNo)
|| isFirstInLine(line, columnNo)
|| !validateComments && isBlockCommentEnd(line, columnNo);
}
Expand All @@ -234,61 +237,51 @@ private boolean isTextSeparatedCorrectlyFromPrevious(String line, int columnNo)
* Checks if the {@code line} at {@code columnNo} is a single space, and not
* preceded by another space.
*
* @param line The line in the file to examine.
* @param line Unicode code point array of line in the file to examine.
* @param columnNo The column position in the {@code line} to examine.
* @return {@code true} if the character at {@code columnNo} is a space, and
* not preceded by another space.
*/
private static boolean isSingleSpace(String line, int columnNo) {
return isSpace(line, columnNo) && !Character.isWhitespace(line.charAt(columnNo - 1));
private static boolean isSingleSpace(int[] line, int columnNo) {
return isSpace(line, columnNo) && !CommonUtil.isCodePointWhitespace(line, columnNo - 1);
}

/**
* Checks if the {@code line} at {@code columnNo} is a space.
*
* @param line The line in the file to examine.
* @param line Unicode code point array of line in the file to examine.
* @param columnNo The column position in the {@code line} to examine.
* @return {@code true} if the character at {@code columnNo} is a space.
*/
private static boolean isSpace(String line, int columnNo) {
return line.charAt(columnNo) == ' ';
}

/**
* Checks if the {@code line} at {@code columnNo} is a whitespace character.
*
* @param line The line in the file to examine.
* @param columnNo The column position in the {@code line} to examine.
* @return {@code true} if the character at {@code columnNo} is a
* whitespace.
*/
private static boolean isWhitespace(String line, int columnNo) {
return Character.isWhitespace(line.charAt(columnNo));
private static boolean isSpace(int[] line, int columnNo) {
return line[columnNo] == ' ';
}

/**
* Checks if the {@code line} up to and including {@code columnNo} is all
* non-whitespace text encountered.
*
* @param line The line in the file to examine.
* @param line Unicode code point array of line in the file to examine.
* @param columnNo The column position in the {@code line} to examine.
* @return {@code true} if the column position is the first non-whitespace
* text on the {@code line}.
*/
private static boolean isFirstInLine(String line, int columnNo) {
return CommonUtil.isBlank(line.substring(0, columnNo));
private static boolean isFirstInLine(int[] line, int columnNo) {
return CodePointUtil.isBlank(Arrays.copyOfRange(line, 0, columnNo));
}

/**
* Checks if the {@code line} at {@code columnNo} is the end of a comment,
* '*&#47;'.
*
* @param line The line in the file to examine.
* @param line Unicode code point array of line in the file to examine.
* @param columnNo The column position in the {@code line} to examine.
* @return {@code true} if the previous text is a end comment block.
*/
private static boolean isBlockCommentEnd(String line, int columnNo) {
return line.substring(0, columnNo).trim().endsWith("*/");
private static boolean isBlockCommentEnd(int[] line, int columnNo) {
final int[] strippedLine = CodePointUtil
.stripTrailing(Arrays.copyOfRange(line, 0, columnNo));
return CodePointUtil.endsWith(strippedLine, "*/");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,32 @@ public static boolean hasWhitespaceBefore(int index, int... codePoints) {
.allMatch(Character::isWhitespace);
}

/**
* Removes trailing whitespaces.
*
* @param codePoints array of unicode code points
* @return unicode code points array with trailing whitespaces removed
*/
public static int[] stripTrailing(int... codePoints) {
int lastIndex = codePoints.length;
while (CommonUtil.isCodePointWhitespace(codePoints, lastIndex - 1)) {
lastIndex--;
}
return Arrays.copyOfRange(codePoints, 0, lastIndex);
}

/**
* Tests if the unicode code points array
* ends with the specified suffix.
*
* @param suffix the suffix
* @param codePoints the array of unicode code points to check
* @return {@code true}, if the unicode code points array ends with provided suffix
*/
public static boolean endsWith(int[] codePoints, String suffix) {
final int startIndex = codePoints.length - suffix.length();
return startIndex > -1 && Arrays.equals(Arrays
.copyOfRange(codePoints, startIndex, codePoints.length),
suffix.codePoints().toArray());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -159,4 +159,41 @@ public void testEmpty() throws Exception {
verifyWithInlineConfigParser(
getPath("InputSingleSpaceSeparatorEmpty.java"), expected);
}

@Test
public void testSpaceErrorsWithEmoji() throws Exception {
final String[] expected = {
"14:18: " + getCheckMessage(MSG_KEY),
"16:17: " + getCheckMessage(MSG_KEY),
"18:27: " + getCheckMessage(MSG_KEY),
"24:46: " + getCheckMessage(MSG_KEY),
"27:9: " + getCheckMessage(MSG_KEY),
"33:17: " + getCheckMessage(MSG_KEY),
"36:14: " + getCheckMessage(MSG_KEY),
"36:25: " + getCheckMessage(MSG_KEY),
"36:37: " + getCheckMessage(MSG_KEY),
"37:43: " + getCheckMessage(MSG_KEY),
"37:46: " + getCheckMessage(MSG_KEY),
"38:15: " + getCheckMessage(MSG_KEY),
"40:16: " + getCheckMessage(MSG_KEY),
};
verifyWithInlineConfigParser(
getPath("InputSingleSpaceSeparatorWithEmoji.java"), expected);
}

@Test
public void testSpaceErrorsAroundCommentsWithEmoji() throws Exception {
final String[] expected = {
"25:22: " + getCheckMessage(MSG_KEY),
"25:26: " + getCheckMessage(MSG_KEY),
"26:26: " + getCheckMessage(MSG_KEY),
"27:13: " + getCheckMessage(MSG_KEY),
"34:8: " + getCheckMessage(MSG_KEY),
"36:37: " + getCheckMessage(MSG_KEY),
"38:46: " + getCheckMessage(MSG_KEY),
"40:24: " + getCheckMessage(MSG_KEY),
};
verifyWithInlineConfigParser(
getPath("InputSingleSpaceSeparatorCommentsWithEmoji.java"), expected);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
SingleSpaceSeparator
validateComments = true
*/

package com.puppycrawl.tools.checkstyle.checks.whitespace.singlespaceseparator;

public class InputSingleSpaceSeparatorCommentsWithEmoji {


String s1 = "🧐😉 assa "; // ok
String s2 = "🧐😉" + " " + "assa "; // ok
String s3 = "🧐" + "🎄 "; // ok
String s4
= "da🎄"; // ok
private void foo(String s) {
if (s.equals("🤩🎄") ){ // ok
foo(s);
}
}

/* ok */ /*🧐*/ String s = "🎄😉";
String /* 🧐 ok */ st = "🎄 assa"; // 2 violations
String str = "🤩🎄"; // violation 'Use a single space to separate non-whitespace characters'
; String j = ""; // violation 'Use a single space to separate non-whitespace characters'
/**
* ok
*/
void foo2() {
/*🧐 🧐 🧐 🧐*/ /* ok */
String s = "🧐 🧐";
} // violation 'Use a single space to separate non-whitespace characters'

private void foo3 (String s) { // ok
// violation above 'Use a single space to separate non-whitespace characters'
if (s.substring(0).equals("da🎄")) { // ok
// violation above 'Use a single space to separate non-whitespace characters'
/*🧐 🧐 🧐*/ /* comment */ if ("🧐".isEmpty()){ // ok
// violation above 'Use a single space to separate non-whitespace characters'
}
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
SingleSpaceSeparator
validateComments = (default)false
*/

package com.puppycrawl.tools.checkstyle.checks.whitespace.singlespaceseparator;

public class InputSingleSpaceSeparatorWithEmoji {

String s1 = "🧐😉 assa "; // ok
String s2 = "🧐😉" + " " + "assa "; // ok
String s3 = "🧐" + "🎄 "; // violation 'Use a single space to separate non-whitespace characters'
String s4
= "da🎄"; // violation 'Use a single space to separate non-whitespace characters'
private void foo(String s) {
if (s.equals("🤩🎄") ){ // violation 'Use a single space to separate non-whitespace characters'
foo(s);
}
}

/* ok */ /*🧐*/ String s = "🎄😉";
String /* 🧐 block comment ok */ st = "🎄 assa";
// violation above 'Use a single space to separate non-whitespace characters'
String str = "🤩🎄"; // Multiple whitespaces before comment
; String j = ""; // violation 'Use a single space to separate non-whitespace characters'
/**
* ok
*/
void foo2() {
/* ok */
String s = "🧐 🧐"; // violation 'Use a single space to separate non-whitespace characters'
} // ok

private void foo3 (String s) { // 3 violations
if (s.substring(0).equals("da🎄") ) { // 2 violations
if ("🧐". // violation 'Use a single space to separate non-whitespace characters'
isEmpty()){
/*🧐*/ } else { // violation 'Use a single space to separate non-whitespace characters'
}
}

}
}

0 comments on commit d9f7a85

Please sign in to comment.