Skip to content

Commit

Permalink
Issue checkstyle#14872: no violation on casting fix
Browse files Browse the repository at this point in the history
  • Loading branch information
mohitsatr committed Nov 26, 2024
1 parent 7868e65 commit d460e7c
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 37 deletions.
2 changes: 1 addition & 1 deletion config/checkstyle-checks.xml
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@
SL_ASSIGN, SR_ASSIGN, STAR_ASSIGN, LAMBDA, TEXT_BLOCK_LITERAL_BEGIN, LAND,
LOR, LITERAL_INSTANCEOF, GT, LT, GE, LE, EQUAL, NOT_EQUAL, UNARY_MINUS,
UNARY_PLUS, INC, DEC, LNOT, BNOT, POST_INC, POST_DEC, BOR, BXOR, BAND,
QUESTION"/>
QUESTION, TYPECAST"/>
</module>
<module name="UnnecessarySemicolonAfterOuterTypeDeclaration"/>
<module name="UnnecessarySemicolonAfterTypeMemberDeclaration"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,9 @@
* <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#POST_INC">
* POST_INC</a>,
* <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#POST_DEC">
* POST_DEC</a>.
* POST_DEC</a>,
* <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#TYPECAST">
* TYPECAST</a>.
* </li>
* </ul>
*
Expand Down Expand Up @@ -394,6 +396,7 @@ public int[] getDefaultTokens() {
TokenTypes.BNOT,
TokenTypes.POST_INC,
TokenTypes.POST_DEC,
TokenTypes.TYPECAST,
};
}

Expand Down Expand Up @@ -445,6 +448,7 @@ public int[] getAcceptableTokens() {
TokenTypes.BOR,
TokenTypes.BAND,
TokenTypes.QUESTION,
TokenTypes.TYPECAST,
};
}

Expand All @@ -467,42 +471,83 @@ else if (ast.getType() == TokenTypes.QUESTION) {
.forEach(unnecessaryChild -> log(unnecessaryChild, MSG_EXPR));
}
else if (parent.getType() != TokenTypes.ANNOTATION_MEMBER_VALUE_PAIR) {
final int type = ast.getType();
final boolean surrounded = isSurrounded(ast);
// An identifier surrounded by parentheses.
if (surrounded && type == TokenTypes.IDENT) {
parentToSkip = ast.getParent();
log(ast, MSG_IDENT, ast.getText());
}
// A literal (numeric or string) surrounded by parentheses.
else if (surrounded && TokenUtil.isOfType(type, LITERALS)) {
parentToSkip = ast.getParent();
if (type == TokenTypes.STRING_LITERAL) {
log(ast, MSG_STRING,
chopString(ast.getText()));
}
else if (type == TokenTypes.TEXT_BLOCK_LITERAL_BEGIN) {
// Strip newline control characters to keep message as single-line, add
// quotes to make string consistent with STRING_LITERAL
final String logString = QUOTE
+ NEWLINE.matcher(
ast.getFirstChild().getText()).replaceAll("\\\\n")
+ QUOTE;
log(ast, MSG_STRING, chopString(logString));
}
else {
log(ast, MSG_LITERAL, ast.getText());
}
}
// The rhs of an assignment surrounded by parentheses.
else if (TokenUtil.isOfType(type, ASSIGNMENTS)) {
assignDepth++;
final DetailAST last = ast.getLastChild();
if (last.getType() == TokenTypes.RPAREN) {
log(ast, MSG_ASSIGN);
}
checkASTSurrounded(ast);
}
}

/**
* Finds and logs if {@code LITERALS},{@code IDENTS}, {@code ASSIGNMENTS}
* and {@TYPECASTS} are surrounded by parentheses.
*
* @param ast the {@code DetailAST} to check.
*/
private void checkASTSurrounded(DetailAST ast) {
final int type = ast.getType();
final boolean surrounded = isSurrounded(ast);
// An identifier surrounded by parentheses.
if (surrounded && type == TokenTypes.IDENT) {
parentToSkip = ast.getParent();
log(ast, MSG_IDENT, ast.getText());
}
// A literal (numeric or string) surrounded by parentheses.
else if (surrounded && TokenUtil.isOfType(type, LITERALS)) {
checkLiteral(ast);
}
// The rhs of an assignment surrounded by parentheses.
else if (TokenUtil.isOfType(type, ASSIGNMENTS)) {
assignDepth++;
final DetailAST last = ast.getLastChild();
if (last.getType() == TokenTypes.RPAREN) {
log(ast, MSG_ASSIGN);
}
}
// A typecast surrounded by parentheses.
else if (surrounded && type == TokenTypes.TYPECAST
&& isTypeCaseSurrounded(ast)) {
log(ast, MSG_EXPR);
}
}

/**
* Checks and logs if the given {@code LITERAL} is surrounded by parentheses.
*
* @param ast the {@code DetailAST} to check.
*/
private void checkLiteral(DetailAST ast) {
final int type = ast.getType();
parentToSkip = ast.getParent();
if (type == TokenTypes.STRING_LITERAL) {
log(ast, MSG_STRING,
chopString(ast.getText()));
}
else if (type == TokenTypes.TEXT_BLOCK_LITERAL_BEGIN) {
// Strip newline control characters to keep message as single-line, add
// quotes to make string consistent with STRING_LITERAL
final String logString = QUOTE
+ NEWLINE.matcher(
ast.getFirstChild().getText()).replaceAll("\\\\n")
+ QUOTE;
log(ast, MSG_STRING, chopString(logString));
}
else {
log(ast, MSG_LITERAL, ast.getText());
}
}

/**
* Checks if the given {@code TYPECAST} is surrounded by parentheses.
*
* @param ast the {@code DetailAST} to check if it is surrounded by
* parentheses.
* @return {@code true} if is surrounded by
* parentheses.
*/
private boolean isTypeCaseSurrounded(DetailAST ast) {
final DetailAST parent = ast.getParent();
final int parentType = parent.getType();
return parentType != TokenTypes.DOT
&& !TokenUtil.isOfType(parentType, ASSIGNMENTS)
&& parentType != TokenTypes.EXPR;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
}
&lt;/pre&gt;</description>
<properties>
<property default-value="EXPR,IDENT,NUM_DOUBLE,NUM_FLOAT,NUM_INT,NUM_LONG,STRING_LITERAL,LITERAL_NULL,LITERAL_FALSE,LITERAL_TRUE,ASSIGN,BAND_ASSIGN,BOR_ASSIGN,BSR_ASSIGN,BXOR_ASSIGN,DIV_ASSIGN,MINUS_ASSIGN,MOD_ASSIGN,PLUS_ASSIGN,SL_ASSIGN,SR_ASSIGN,STAR_ASSIGN,LAMBDA,TEXT_BLOCK_LITERAL_BEGIN,LAND,LOR,LITERAL_INSTANCEOF,GT,LT,GE,LE,EQUAL,NOT_EQUAL,UNARY_MINUS,UNARY_PLUS,INC,DEC,LNOT,BNOT,POST_INC,POST_DEC"
<property default-value="EXPR,IDENT,NUM_DOUBLE,NUM_FLOAT,NUM_INT,NUM_LONG,STRING_LITERAL,LITERAL_NULL,LITERAL_FALSE,LITERAL_TRUE,ASSIGN,BAND_ASSIGN,BOR_ASSIGN,BSR_ASSIGN,BXOR_ASSIGN,DIV_ASSIGN,MINUS_ASSIGN,MOD_ASSIGN,PLUS_ASSIGN,SL_ASSIGN,SR_ASSIGN,STAR_ASSIGN,LAMBDA,TEXT_BLOCK_LITERAL_BEGIN,LAND,LOR,LITERAL_INSTANCEOF,GT,LT,GE,LE,EQUAL,NOT_EQUAL,UNARY_MINUS,UNARY_PLUS,INC,DEC,LNOT,BNOT,POST_INC,POST_DEC,TYPECAST"
name="tokens"
type="java.lang.String[]"
validation-type="tokenSet">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,28 @@ public void testDefault() throws Exception {
getPath("InputUnnecessaryParenthesesOperatorsAndCasts.java"), expected);
}

@Test
public void testCasts1() throws Exception {

final String[] expected = {
"23:18: " + getCheckMessage(MSG_EXPR),
"23:43: " + getCheckMessage(MSG_EXPR),
"30:11: " + getCheckMessage(MSG_ASSIGN),
"32:11: " + getCheckMessage(MSG_ASSIGN),
"32:22: " + getCheckMessage(MSG_EXPR),
"45:18: " + getCheckMessage(MSG_EXPR),
"61:15: " + getCheckMessage(MSG_EXPR),
"66:31: " + getCheckMessage(MSG_EXPR),
"71:40: " + getCheckMessage(MSG_EXPR),
"78:22: " + getCheckMessage(MSG_EXPR),
"89:14: " + getCheckMessage(MSG_EXPR),
"95:28: " + getCheckMessage(MSG_EXPR),
"100:26: " + getCheckMessage(MSG_EXPR),
};
verifyWithInlineConfigParser(
getPath("InputUnnecessaryParenthesesCasts.java"), expected);
}

@Test
public void test15Extensions() throws Exception {
final String[] expected = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
UnnecessaryParentheses
tokens = (default)EXPR, IDENT, NUM_DOUBLE, NUM_FLOAT, NUM_INT, NUM_LONG, \
STRING_LITERAL, LITERAL_NULL, LITERAL_FALSE, LITERAL_TRUE, ASSIGN, \
BAND_ASSIGN, BOR_ASSIGN, BSR_ASSIGN, BXOR_ASSIGN, DIV_ASSIGN, \
MINUS_ASSIGN, MOD_ASSIGN, PLUS_ASSIGN, SL_ASSIGN, SR_ASSIGN, STAR_ASSIGN, \
LAMBDA, TEXT_BLOCK_LITERAL_BEGIN, LAND, LITERAL_INSTANCEOF, GT, LT, GE, \
LE, EQUAL, NOT_EQUAL, UNARY_MINUS, UNARY_PLUS, INC, DEC, LNOT, BNOT, \
POST_INC, POST_DEC, TYPECAST
*/

package com.puppycrawl.tools.checkstyle.checks.coding.unnecessaryparentheses;
import java.util.HashSet;
import java.util.Arrays;
public class InputUnnecessaryParenthesesCasts {
public void valid1() {
int x = 23;
int y = 44;
float k = 12f;

int d = ((int) 100f) + 100 * 2 / ((int) 12.5f) + (int) 90f; // 2 violations

y = (int) (22.2 * 2) / ((int) 8f + 5);

double arg2 = 23.2;
int i = (int) arg2;

i = ((int) arg2); // violation 'Unnecessary parentheses around assignment right-hand side'

x = (2 * 2 /((int) k)); // 2 violations

int par = ((int)2f * 2) / 4;
}

public void fooConditionals() {
int x = 12;
float xy = 40f;
int y = 0;
double limit = 3.2;
boolean finished = true;
boolean result = false;

if(x >= ((int)xy) // violation 'Unnecessary parentheses around expression.'
| (y==1 | x>=1)) {
xy--;
}

if (!((int) xy > y)
&& x < 20) {
x++;
}

char letter = 'a';
if (35 + (int) letter == 100) {
x++;
}

boolean checkone = true;
if (!((boolean) checkone)) {
// violation above 'Unnecessary parentheses around expression.'
checkone = false;
}

for (int j = 0; j >= ((int) limit); j++) {
// violation above 'Unnecessary parentheses around expression.'
y+=1;
}

for(int j = 10; !finished && !((boolean) (j > 5)) ; j++){
// violation above 'Unnecessary parentheses around expression.'
break;
}

String filevalue = "FILEVALUE";
if (!finished
|| !((boolean) filevalue.contains("O"))) {
// violation above 'Unnecessary parentheses around expression.'
filevalue += "F";
}

if (result && finished
|| ((int)23.1 + 21) == 32) {
y--;
}

// violation below 'Unnecessary parentheses around expression.'
if(!((boolean) filevalue.contains("G"))
|| finished) {
x++;
}
String[] a = { "s", "a", "1", "2", "3" };
Arrays.stream(a)
.filter(s -> !((boolean) s.isEmpty()))
// violation above 'Unnecessary parentheses around expression.'
.toArray(String[]::new);

Arrays.stream(a) // violation below 'Unnecessary parentheses around expression.'
.filter(s -> ((boolean) s.isEmpty()))
.toArray(String[]::new);

new HashSet<Integer>()
.stream()
.filter(f -> f > ((int) 1.1 + 200));

y = ((Integer) x).hashCode();
}
}
4 changes: 4 additions & 0 deletions src/xdocs/checks/coding/unnecessaryparentheses.xml
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ if ((++f) &gt; g &amp;&amp; a) { // violation, unnecessary paren
BAND</a>
, <a href="../../apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#QUESTION">
QUESTION</a>
, <a href="../../apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#TYPECAST">
TYPECAST</a>
.
</td>
<td>
Expand Down Expand Up @@ -264,6 +266,8 @@ if ((++f) &gt; g &amp;&amp; a) { // violation, unnecessary paren
POST_INC</a>
, <a href="../../apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#POST_DEC">
POST_DEC</a>
, <a href="../../apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#TYPECAST">
TYPECAST</a>
.
</td>
<td>3.4</td>
Expand Down

0 comments on commit d460e7c

Please sign in to comment.