Skip to content

Commit

Permalink
Issue checkstyle#3839: Added 3 methods to help detect empty LITERAL_C…
Browse files Browse the repository at this point in the history
…ASE. Added corresponding UTs
  • Loading branch information
voidfist committed Mar 11, 2017
1 parent cac09c4 commit bd6f9bc
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 0 deletions.
Expand Up @@ -171,6 +171,10 @@ else if (!hasText(leftCurly)) {
ast.getText());
}
}

if (ast.getType() == TokenTypes.LITERAL_CASE) {
checkForEmptyCase(ast);
}
}

/**
Expand Down Expand Up @@ -236,4 +240,72 @@ private static boolean checkIsAllLinesAreWhitespace(String[] lines, int lineFrom
}
return result;
}

/**
* Checks for empty LITERAL_CASE.
*
* @param ast a {@code DetailAST} value
*/
protected void checkForEmptyCase(DetailAST ast) {
final DetailAST slistToken = ast.getNextSibling();
if (slistToken != null
&& slistToken.getType() == TokenTypes.SLIST) {
if (option == BlockOption.STMT) {
if (!isCaseHavingStmt(slistToken)) {
log(ast.getLineNo(),
ast.getColumnNo(),
MSG_KEY_BLOCK_NO_STMT,
ast.getText());
}
}
else if (!isCaseHavingText(slistToken)) {
log(ast.getLineNo(),
ast.getColumnNo(),
MSG_KEY_BLOCK_EMPTY,
ast.getText());
}
}
}

/**
* Checks if case has any statements.
*
* @param slistAST a {@code DetailAST} value
* @return true if the case related to the SLIST token has atleast one statement
*/
protected boolean isCaseHavingStmt(final DetailAST slistAST) {
DetailAST leftCurly;
for (leftCurly = slistAST.getFirstChild();
leftCurly != null; leftCurly = leftCurly.getNextSibling()) {
if (leftCurly.getFirstChild().getType() != TokenTypes.RCURLY) {
break;
}
}
return leftCurly != null;
}

/**
* Checks if case has any text.
*
* @param slistAST a {@code DetailAST} value
* @return true if the case related to the SLIST token has any text
*/
protected boolean isCaseHavingText(final DetailAST slistAST) {
boolean returnValue = true;
for (DetailAST leftCurly = slistAST.getFirstChild();
leftCurly != null; leftCurly = leftCurly.getNextSibling()) {
if (leftCurly.getType() == TokenTypes.SLIST) {
returnValue = hasText(leftCurly);
}
else {
returnValue = true;
}

if (returnValue) {
break;
}
}
return returnValue;
}

}
Expand Up @@ -157,4 +157,36 @@ public void testInvalidOption() throws Exception {
+ "Cannot set property 'option' to 'invalid_option' in module"));
}
}

@Test
public void testAllowEmptyCaseWithText() throws Exception {
final DefaultConfiguration checkConfig = createCheckConfig(EmptyBlockCheck.class);
checkConfig.addAttribute("option", BlockOption.TEXT.toString());
checkConfig.addAttribute("tokens", "LITERAL_CASE");
final String[] expected = {
"12:21: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "case"),
"17:13: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "case"),
"29:21: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "case"),
"31:29: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "case"),
"32:21: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "case"),
};
verify(checkConfig, getPath("InputEmptyCase.java"), expected);
}

@Test
public void testForbidCaseWithoutStmt() throws Exception {
final DefaultConfiguration checkConfig = createCheckConfig(EmptyBlockCheck.class);
checkConfig.addAttribute("option", BlockOption.STMT.toString());
checkConfig.addAttribute("tokens", "LITERAL_CASE");
final String[] expected = {
"12:21: " + getCheckMessage(MSG_KEY_BLOCK_NO_STMT, "case"),
"17:13: " + getCheckMessage(MSG_KEY_BLOCK_NO_STMT, "case"),
"21:13: " + getCheckMessage(MSG_KEY_BLOCK_NO_STMT, "case"),
"29:21: " + getCheckMessage(MSG_KEY_BLOCK_NO_STMT, "case"),
"31:29: " + getCheckMessage(MSG_KEY_BLOCK_NO_STMT, "case"),
"32:21: " + getCheckMessage(MSG_KEY_BLOCK_NO_STMT, "case"),
"32:32: " + getCheckMessage(MSG_KEY_BLOCK_NO_STMT, "case"),
};
verify(checkConfig, getPath("InputEmptyCase.java"), expected);
}
}
@@ -0,0 +1,36 @@
////////////////////////////////////////////////////////////////////////////////
// Input test file for testing empty LITERAL_CASE.
// Created: 2017
////////////////////////////////////////////////////////////////////////////////
package com.puppycrawl.tools.checkstyle.checks.blocks;

class InputEmptyCase
{
void method1(int a) {
switch (a) {}
switch (a) {case 1:}
switch (a) {case 1:{}} // 1 violation
switch (a) {
case 1:
}
switch (a) {
case 1: // 1 violation
{}
}
switch (a) {
case 1: // 1 violation if checking statements
{// none if checking text
}
}
}

public void method2(char c) {
switch(c) { case 0: } // no violation
switch(c) { case 0: {} } // 1 violation
switch(c) { case 0: method1(0); {} } // no violation
switch(c) { case 0: case 1: {} } // 1 violation
switch(c) { case 0: {} case 1: {// 2 violations if checking statements
}
}
}
}

0 comments on commit bd6f9bc

Please sign in to comment.