diff --git a/pom.xml b/pom.xml
index dee1fc5e041..451514dfb95 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3308,6 +3308,10 @@
com.puppycrawl.tools.checkstyle.checks.whitespace.SingleSpaceSeparatorCheckTest
+
+
+ com.puppycrawl.tools.checkstyle.checks.whitespace.SeparatorWrapCheckTest
+
com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocStyleCheckTest
diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/whitespace/SeparatorWrapCheck.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/whitespace/SeparatorWrapCheck.java
index 9323971bc8b..6d675a391f7 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/checks/whitespace/SeparatorWrapCheck.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/whitespace/SeparatorWrapCheck.java
@@ -19,12 +19,14 @@
package com.puppycrawl.tools.checkstyle.checks.whitespace;
+import java.util.Arrays;
import java.util.Locale;
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.api.TokenTypes;
+import com.puppycrawl.tools.checkstyle.utils.CodePointUtil;
import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
/**
@@ -220,18 +222,20 @@ public void visitToken(DetailAST ast) {
final String text = ast.getText();
final int colNo = ast.getColumnNo();
final int lineNo = ast.getLineNo();
- final String currentLine = getLines()[lineNo - 1];
- final String substringAfterToken =
- currentLine.substring(colNo + text.length()).trim();
- final String substringBeforeToken =
- currentLine.substring(0, colNo).trim();
+ final int[] currentLine = getLineCodePoints(lineNo - 1);
+ final int[] substringAfterToken = CodePointUtil.trim(
+ Arrays.copyOfRange(currentLine, colNo + text.length(), currentLine.length)
+ );
+ final int[] substringBeforeToken = CodePointUtil.trim(
+ Arrays.copyOfRange(currentLine, 0, colNo)
+ );
if (option == WrapOption.EOL
- && substringBeforeToken.isEmpty()) {
+ && substringBeforeToken.length == 0) {
log(ast, MSG_LINE_PREVIOUS, text);
}
else if (option == WrapOption.NL
- && substringAfterToken.isEmpty()) {
+ && substringAfterToken.length == 0) {
log(ast, MSG_LINE_NEW, text);
}
}
diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/utils/CodePointUtil.java b/src/main/java/com/puppycrawl/tools/checkstyle/utils/CodePointUtil.java
index ef4ce47912b..4d3b6974ab2 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/utils/CodePointUtil.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/utils/CodePointUtil.java
@@ -63,12 +63,38 @@ public static boolean hasWhitespaceBefore(int index, int... codePoints) {
*/
public static int[] stripTrailing(int... codePoints) {
int lastIndex = codePoints.length;
- while (CommonUtil.isCodePointWhitespace(codePoints, lastIndex - 1)) {
+ while (lastIndex > 0 && CommonUtil.isCodePointWhitespace(codePoints, lastIndex - 1)) {
lastIndex--;
}
return Arrays.copyOfRange(codePoints, 0, lastIndex);
}
+ /**
+ * Removes leading whitespaces.
+ *
+ * @param codePoints array of unicode code points
+ * @return unicode code points array with leading whitespaces removed
+ */
+ public static int[] stripLeading(int... codePoints) {
+ int startIndex = 0;
+ while (startIndex < codePoints.length
+ && CommonUtil.isCodePointWhitespace(codePoints, startIndex)) {
+ startIndex++;
+ }
+ return Arrays.copyOfRange(codePoints, startIndex, codePoints.length);
+ }
+
+ /**
+ * Removes leading and trailing whitespaces.
+ *
+ * @param codePoints array of unicode code points
+ * @return unicode code points array with leading and trailing whitespaces removed
+ */
+ public static int[] trim(int... codePoints) {
+ final int[] strippedCodePoints = stripTrailing(codePoints);
+ return stripLeading(strippedCodePoints);
+ }
+
/**
* Tests if the unicode code points array
* ends with the specified suffix.
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/checks/whitespace/SeparatorWrapCheckTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/checks/whitespace/SeparatorWrapCheckTest.java
index ee10cfa8500..dcee84e7336 100644
--- a/src/test/java/com/puppycrawl/tools/checkstyle/checks/whitespace/SeparatorWrapCheckTest.java
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/checks/whitespace/SeparatorWrapCheckTest.java
@@ -117,4 +117,18 @@ public void testArrayDeclarator() throws Exception {
getPath("InputSeparatorWrapForArrayDeclarator.java"), expected);
}
+ @Test
+ public void testWithEmoji() throws Exception {
+ final String[] expected = {
+ "13:39: " + getCheckMessage(MSG_LINE_NEW, '['),
+ "16:57: " + getCheckMessage(MSG_LINE_NEW, '['),
+ "19:39: " + getCheckMessage(MSG_LINE_NEW, "..."),
+ "26:19: " + getCheckMessage(MSG_LINE_NEW, '.'),
+ "39:50: " + getCheckMessage(MSG_LINE_NEW, ','),
+ "41:50: " + getCheckMessage(MSG_LINE_NEW, "::"),
+ };
+ verifyWithInlineConfigParser(
+ getPath("InputSeparatorWrapWithEmoji.java"), expected);
+ }
+
}
diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/checks/whitespace/separatorwrap/InputSeparatorWrapWithEmoji.java b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/whitespace/separatorwrap/InputSeparatorWrapWithEmoji.java
new file mode 100644
index 00000000000..c07e6ba3bbb
--- /dev/null
+++ b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/whitespace/separatorwrap/InputSeparatorWrapWithEmoji.java
@@ -0,0 +1,44 @@
+/*
+SeparatorWrap
+option = NL
+tokens = DOT, COMMA,ELLIPSIS, ARRAY_DECLARATOR, METHOD_REF
+
+*/
+
+package com.puppycrawl.tools.checkstyle.checks.whitespace.separatorwrap;
+
+import java.util.Arrays;
+
+public class InputSeparatorWrapWithEmoji {
+ protected String[] s1 = new String[
+ /*π with text */ ] {"aabπ", "aπaπba"}; // violation above ''\[' should be on a new line'
+
+ /* emojiπarray */ protected String[] s2 = new String[
+ ] {"π₯³", "π ", "π¨"}; // violation above''\[' should be on a new line'
+
+ /*ππ» ππ»*/ public void test1(String...
+ parameters) { // violation above ''...' should be on a new line'
+ }
+
+ public void test2(String
+ /* ππ»ππ» */ ...parameters) { // ok
+ String s = "ffffooooString";
+ /* π§π₯³ */ s.
+ isEmpty(); // violation above ''.' should be on a new line'
+ try {
+ test2("2", s);
+ } catch (Exception e) {}
+
+ test1("1"
+ /*π§ sda π₯³ */ ,s); // ok
+
+ }
+ void goodCase() {
+ String[] stringArray =
+ {
+ "π", "ππ", "QWERTY", "π§π»", "John",
+ /*π€π»*/ }; // violation above '',' should be on a new line'
+ /*π€π» π€π»*/ Arrays.sort(stringArray, String::
+ compareToIgnoreCase); // violation above ''::' should be on a new line'
+ }
+}