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 Dec 2, 2024
1 parent b050607 commit 4ecae8f
Show file tree
Hide file tree
Showing 7 changed files with 294 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);
}
findUnnecessaryParenthesesInAst(ast);
}
}

/**
* Finds and logs if {@code LITERAL},{@code IDENT}, {@code ASSIGNMENT}
* and {@code TYPECAST} are surrounded by parentheses.
*
* @param ast the {@code DetailAST} to check.
*/
private void findUnnecessaryParenthesesInAst(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)) {
findUnnecessaryParenthesesInLiterals(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 findUnnecessaryParenthesesInLiterals(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 static boolean isTypeCaseSurrounded(DetailAST ast) {
final DetailAST parent = ast.getParent();
final int parentType = parent.getType();
return parentType != TokenTypes.DOT
&& parentType != TokenTypes.EXPR
&& !TokenUtil.isOfType(parentType, ASSIGNMENTS);
}

@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,36 @@ public void testDefault() throws Exception {
getPath("InputUnnecessaryParenthesesOperatorsAndCasts.java"), expected);
}

@Test
public void testCasts1() throws Exception {
final String[] expected = {
"20:18: " + getCheckMessage(MSG_EXPR),
"20:43: " + getCheckMessage(MSG_EXPR),
"30:11: " + getCheckMessage(MSG_ASSIGN),
"34:11: " + getCheckMessage(MSG_ASSIGN),
"34:22: " + getCheckMessage(MSG_EXPR),
"49:19: " + getCheckMessage(MSG_EXPR),
"69:15: " + getCheckMessage(MSG_EXPR),
"78:31: " + getCheckMessage(MSG_EXPR),
"88:40: " + getCheckMessage(MSG_EXPR),
};
verifyWithInlineConfigParser(
getPath("InputUnnecessaryParenthesesCasts1.java"), expected);
}

@Test
public void testCasts2() throws Exception {
final String[] expected = {
"30:22: " + getCheckMessage(MSG_EXPR),
"43:15: " + getCheckMessage(MSG_EXPR),
"54:32: " + getCheckMessage(MSG_EXPR),
"62:30: " + getCheckMessage(MSG_EXPR),
"73:14: " + getCheckMessage(MSG_EXPR),
};
verifyWithInlineConfigParser(
getPath("InputUnnecessaryParenthesesCasts2.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,97 @@
/*
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;
public class InputUnnecessaryParenthesesCasts1 {
public void valid1() {
int x = 23;
int y = 44;
float k = 12f;

int d = ((int) 100f) + 100 * 2 / ((int) 12.5) + (int) 90f;
// 2 violations above:
// 'Unnecessary parentheses around expression'
// 'Unnecessary parentheses around expression'
int p = (int) 110f + 10 * 2 / (int) 10f + (int) 32.2;

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'

p = (int) arg2;

x = (2 * 2 /((int) k));
// 2 violations above:
// 'Unnecessary parentheses around assignment right-hand side'
// 'Unnecessary parentheses around expression'
x = 2 * 2 / (int) k;

int par = ((int)2f * 2) / 4;
y = ((Integer) x).hashCode();

int py = 12;
float xy = 40f;
int yp = 0;
boolean finished = true;
boolean result = false;

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

if(yp >= (int)xy
|| (py ==1 | py >=1)) {
xy++;
}

if (!((int) xy > yp)
&& py < 20) {
py++;
}

if (35 + (int) 'a' == 100) {
py++;
}

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

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

for (int lp =0; lp >= (int) limit; lp++) {
py--;
break;
}

for(int j = 10; !finished && !((boolean) (j > 5)) ; j++){
// violation above 'Unnecessary parentheses around expression.'
break;
}
for(int jp = 9; !finished || !(boolean) (jp >5); jp++){
checkone = false;
break;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
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 static java.lang.Math.abs;
import java.util.Arrays;
import java.util.HashSet;

public class InputUnnecessaryParenthesesCasts2 {
public void fooConditionals() {
int x = 23;
int y = 44;
float k = 12f;
boolean finished = true;
boolean result = false;

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

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

// violation below 'Unnecessary parentheses around expression.'
if (!((boolean) filevalue.contains("G"))
|| finished) {
x++;
}
else if (!(boolean) filevalue.contains("P") || finished) {
filevalue += "p";
}

String[] a = {"s", "a", "1", "2", "3"};
String[] abr = {"18", "z", "w", "30", "u", "vel"};
Arrays.stream(a)
.filter(s -> !((boolean) s.isEmpty()))
// violation above 'Unnecessary parentheses around expression.'
.toArray(String[]::new);

Arrays.stream(abr).filter(s -> !(boolean) s.isEmpty())
.toArray(String[]::new);

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

Arrays.stream(abr)
.filter(s -> (boolean) s.isEmpty())
.toArray(String[]::new);

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

// violation below 'Unnecessary parentheses around expression.'
if (((double) abs(10 - 2))
/ 2 <= 0.01) {
y += 10;
}
else if ((double) abs(10 - 2) / 2 >= 0.02) {
x += 2;
}
}
}
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 4ecae8f

Please sign in to comment.