Skip to content

Commit

Permalink
Issue #10924: Update GenericWhitespaceCheck to use code points
Browse files Browse the repository at this point in the history
  • Loading branch information
MUzairS15 authored and romani committed Mar 16, 2022
1 parent 2060f62 commit cb8b26f
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 22 deletions.
Expand Up @@ -19,10 +19,13 @@

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

import java.util.stream.IntStream;

import com.puppycrawl.tools.checkstyle.FileStatefulCheck;
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;

/**
Expand Down Expand Up @@ -191,16 +194,16 @@ public void visitToken(DetailAST ast) {
* @param ast the token to check
*/
private void processEnd(DetailAST ast) {
final String line = getLine(ast.getLineNo() - 1);
final int[] line = getLineCodePoints(ast.getLineNo() - 1);
final int before = ast.getColumnNo() - 1;
final int after = ast.getColumnNo() + 1;

if (before >= 0 && Character.isWhitespace(line.charAt(before))
if (before >= 0 && CommonUtil.isCodePointWhitespace(line, before)
&& !containsWhitespaceBefore(before, line)) {
log(ast, MSG_WS_PRECEDED, CLOSE_ANGLE_BRACKET);
}

if (after < line.length()) {
if (after < line.length) {
// Check if the last Generic, in which case must be a whitespace
// or a '(),[.'.
if (depth == 1) {
Expand All @@ -216,10 +219,10 @@ private void processEnd(DetailAST ast) {
* Process Nested generics.
*
* @param ast token
* @param line line content
* @param line unicode code points array of line
* @param after position after
*/
private void processNestedGenerics(DetailAST ast, String line, int after) {
private void processNestedGenerics(DetailAST ast, int[] line, int after) {
// In a nested Generic type, so can only be a '>' or ',' or '&'

// In case of several extends definitions:
Expand All @@ -228,7 +231,10 @@ private void processNestedGenerics(DetailAST ast, String line, int after) {
// ^
// should be whitespace if followed by & -+
//
final int indexOfAmp = line.indexOf('&', after);
final int indexOfAmp = IntStream.range(after, line.length)
.filter(index -> line[index] == '&')
.findFirst()
.orElse(-1);
if (indexOfAmp >= 1
&& containsWhitespaceBetween(after, indexOfAmp, line)) {
if (indexOfAmp - after == 0) {
Expand All @@ -238,7 +244,7 @@ else if (indexOfAmp - after != 1) {
log(ast, MSG_WS_FOLLOWED, CLOSE_ANGLE_BRACKET);
}
}
else if (line.charAt(after) == ' ') {
else if (line[after] == ' ') {
log(ast, MSG_WS_FOLLOWED, CLOSE_ANGLE_BRACKET);
}
}
Expand All @@ -247,11 +253,11 @@ else if (line.charAt(after) == ' ') {
* Process Single-generic.
*
* @param ast token
* @param line line content
* @param line unicode code points array of line
* @param after position after
*/
private void processSingleGeneric(DetailAST ast, String line, int after) {
final char charAfter = line.charAt(after);
private void processSingleGeneric(DetailAST ast, int[] line, int after) {
final char charAfter = Character.toChars(line[after])[0];
if (isGenericBeforeMethod(ast) || isGenericBeforeCtor(ast)) {
if (Character.isWhitespace(charAfter)) {
log(ast, MSG_WS_FOLLOWED, CLOSE_ANGLE_BRACKET);
Expand Down Expand Up @@ -303,7 +309,7 @@ private static boolean isAfterMethodReference(DetailAST genericEnd) {
* @param ast the token to check
*/
private void processStart(DetailAST ast) {
final String line = getLine(ast.getLineNo() - 1);
final int[] line = getLineCodePoints(ast.getLineNo() - 1);
final int before = ast.getColumnNo() - 1;
final int after = ast.getColumnNo() + 1;

Expand All @@ -321,19 +327,19 @@ private void processStart(DetailAST ast) {
|| grandparent.getType() == TokenTypes.METHOD_DEF
|| isGenericBeforeCtor(ast)) {
// Require whitespace
if (!Character.isWhitespace(line.charAt(before))) {
if (!CommonUtil.isCodePointWhitespace(line, before)) {
log(ast, MSG_WS_NOT_PRECEDED, OPEN_ANGLE_BRACKET);
}
}
// Whitespace not required
else if (Character.isWhitespace(line.charAt(before))
else if (CommonUtil.isCodePointWhitespace(line, before)
&& !containsWhitespaceBefore(before, line)) {
log(ast, MSG_WS_PRECEDED, OPEN_ANGLE_BRACKET);
}
}

if (after < line.length()
&& Character.isWhitespace(line.charAt(after))) {
if (after < line.length
&& CommonUtil.isCodePointWhitespace(line, after)) {
log(ast, MSG_WS_FOLLOWED, OPEN_ANGLE_BRACKET);
}
}
Expand All @@ -344,13 +350,13 @@ else if (Character.isWhitespace(line.charAt(before))
*
* @param fromIndex the index to start the search from. Inclusive
* @param toIndex the index to finish the search. Exclusive
* @param line the line to check
* @param line the unicode code points array of line to check
* @return whether there are only whitespaces (or nothing)
*/
private static boolean containsWhitespaceBetween(int fromIndex, int toIndex, String line) {
private static boolean containsWhitespaceBetween(int fromIndex, int toIndex, int... line) {
boolean result = true;
for (int i = fromIndex; i < toIndex; i++) {
if (!Character.isWhitespace(line.charAt(i))) {
if (!CommonUtil.isCodePointWhitespace(line, i)) {
result = false;
break;
}
Expand All @@ -361,13 +367,13 @@ private static boolean containsWhitespaceBetween(int fromIndex, int toIndex, Str
/**
* Returns whether the specified string contains only whitespace up to specified index.
*
* @param before the index to start the search from. Inclusive
* @param line the index to finish the search. Exclusive
* @param before the index to finish the search. Exclusive
* @param line the unicode code points array of line to check
* @return {@code true} if there are only whitespaces,
* false if there is nothing before or some other characters
*/
private static boolean containsWhitespaceBefore(int before, String line) {
return before != 0 && CommonUtil.hasWhitespaceBefore(before, line);
private static boolean containsWhitespaceBefore(int before, int... line) {
return before != 0 && CodePointUtil.hasWhitespaceBefore(before, line);
}

/**
Expand Down
Expand Up @@ -151,6 +151,19 @@ public void testGenericEndsTheLine() throws Exception {
getPath("InputGenericWhitespaceEndsTheLine.java"), expected);
}

@Test
public void testGenericWhitespaceWithEmoji() throws Exception {
final String[] expected = {
"35:2: " + getCheckMessage(MSG_WS_PRECEDED, '>'),
"40:35: " + getCheckMessage(MSG_WS_PRECEDED, '<'),
"40:42: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
"44:28: " + getCheckMessage(MSG_WS_NOT_PRECEDED, '<'),
"45:53: " + getCheckMessage(MSG_WS_PRECEDED, '<'),
};
verifyWithInlineConfigParser(
getPath("InputGenericWhitespaceWithEmoji.java"), expected);
}

@Test
public void testGetAcceptableTokens() {
final GenericWhitespaceCheck genericWhitespaceCheckObj = new GenericWhitespaceCheck();
Expand Down
@@ -0,0 +1,49 @@
/*
GenericWhitespace
*/

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

import java.util.Collections;
import java.util.List;
import java.util.function.Supplier;

public class InputGenericWhitespaceWithEmoji {

/* 👇🏻dsad */public static class SomeClass { /* 😂 */ // ok

public static class Nested<V> {

private Nested() {

}
}
}
public <V> void methodName(V value) {

/* 👉🏻 😆 */ Supplier<?> t = InputGenericWhitespaceMethodRef1.Nested2<V>::new;

// 🎄 da
List<List<String>[]>
/*😂 🤛🏻 asd*/ listOfListOFArrays;

}

interface NumberEnum<T
> { /*inner😆 enum*/} // violation ''>' is preceded with whitespace'

public int getConstructor(Class<?>... parameterTypes)
{
Collections.<Object>emptySet();
Collections. /*da sd😆sd*/ <Object> emptySet(); // 2 violations
return 666;
}
Object ok2 = new <String>Outer.Inner();
Object notOkStart = new<String>Outer.Inner(); // violation ''<' is not preceded with whitespace'
/* 😆asd*/ public static class IntEnumValueType3 <E extends Enum<E>> {
// violation above ''<' is preceded with whitespace'
}

}

0 comments on commit cb8b26f

Please sign in to comment.