Issue #3655: Fix NPE in NeedBraces on single line default stmt

This commit is contained in:
liscju 2016-12-21 07:58:23 +01:00 committed by Roman Ivanov
parent 914dd9994c
commit 0fdbbda102
3 changed files with 75 additions and 11 deletions

View File

@ -204,15 +204,30 @@ public class NeedBracesCheck extends AbstractCheck {
&& ast.findFirstToken(TokenTypes.LITERAL_IF) != null) {
isElseIf = true;
}
final boolean isDefaultInAnnotation = isDefaultInAnnotation(ast);
final boolean skipStatement = isSkipStatement(ast);
final boolean skipEmptyLoopBody = allowEmptyLoopBody && isEmptyLoopBody(ast);
if (slistAST == null && !isElseIf && !skipStatement && !skipEmptyLoopBody) {
if (slistAST == null && !isElseIf && !isDefaultInAnnotation
&& !skipStatement && !skipEmptyLoopBody) {
log(ast.getLineNo(), MSG_KEY_NEED_BRACES, ast.getText());
}
}
/**
* Checks if ast is default in annotation
* @param ast ast to test.
* @return true if current ast is default and it is part of annatation.
*/
private boolean isDefaultInAnnotation(DetailAST ast) {
boolean isDefaultInAnnotation = false;
if (ast.getType() == TokenTypes.LITERAL_DEFAULT
&& ast.getParent().getType() == TokenTypes.ANNOTATION_FIELD_DEF) {
isDefaultInAnnotation = true;
}
return isDefaultInAnnotation;
}
/**
* Checks if current statement can be skipped by "need braces" warning.
* @param statement if, for, while, do-while, lambda, else, case, default statements.
@ -410,6 +425,7 @@ public class NeedBracesCheck extends AbstractCheck {
* {@code
* case 1: doSomeStuff(); break;
* case 2: doSomeStuff(); break;
* case 3: ;
* }
* </p>
* @param literalCase {@link TokenTypes#LITERAL_CASE case statement}.
@ -418,12 +434,17 @@ public class NeedBracesCheck extends AbstractCheck {
private static boolean isSingleLineCase(DetailAST literalCase) {
boolean result = false;
final DetailAST slist = literalCase.getNextSibling();
final DetailAST block = slist.getFirstChild();
if (block.getType() != TokenTypes.SLIST) {
final DetailAST caseBreak = slist.findFirstToken(TokenTypes.LITERAL_BREAK);
final boolean atOneLine = literalCase.getLineNo() == block.getLineNo();
if (caseBreak != null) {
result = atOneLine && block.getLineNo() == caseBreak.getLineNo();
if (slist == null) {
result = true;
}
else {
final DetailAST block = slist.getFirstChild();
if (block.getType() != TokenTypes.SLIST) {
final DetailAST caseBreak = slist.findFirstToken(TokenTypes.LITERAL_BREAK);
final boolean atOneLine = literalCase.getLineNo() == block.getLineNo();
if (caseBreak != null) {
result = atOneLine && block.getLineNo() == caseBreak.getLineNo();
}
}
}
return result;
@ -442,9 +463,14 @@ public class NeedBracesCheck extends AbstractCheck {
private static boolean isSingleLineDefault(DetailAST literalDefault) {
boolean result = false;
final DetailAST slist = literalDefault.getNextSibling();
final DetailAST block = slist.getFirstChild();
if (block.getType() != TokenTypes.SLIST) {
result = literalDefault.getLineNo() == block.getLineNo();
if (slist == null) {
result = true;
}
else {
final DetailAST block = slist.getFirstChild();
if (block != null && block.getType() != TokenTypes.SLIST) {
result = literalDefault.getLineNo() == block.getLineNo();
}
}
return result;
}

View File

@ -115,6 +115,16 @@ public class NeedBracesCheckTest extends BaseCheckTestSupport {
verify(checkConfig, getPath("InputBracesSingleLineStatements.java"), expected);
}
@Test
public void testSingleLineCaseDefault2() throws Exception {
final DefaultConfiguration checkConfig =
createCheckConfig(NeedBracesCheck.class);
checkConfig.addAttribute("tokens", "LITERAL_CASE, LITERAL_DEFAULT");
checkConfig.addAttribute("allowSingleLineStatement", "true");
final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
verify(checkConfig, getPath("InputNeedBracesEmptyDefault.java"), expected);
}
@Test
public void testCycles() throws Exception {
final DefaultConfiguration checkConfig = createCheckConfig(NeedBracesCheck.class);
@ -178,4 +188,13 @@ public class NeedBracesCheckTest extends BaseCheckTestSupport {
};
verify(checkConfig, getPath("InputNeedBracesNoBodyLoops.java"), expected);
}
@Test
public void testEmptySingleLineDefaultStmt() throws Exception {
final DefaultConfiguration checkConfig = createCheckConfig(NeedBracesCheck.class);
checkConfig.addAttribute("tokens", "LITERAL_DEFAULT");
checkConfig.addAttribute("allowSingleLineStatement", "true");
final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
verify(checkConfig, getPath("InputNeedBracesEmptyDefault.java"), expected);
}
}

View File

@ -0,0 +1,19 @@
package com.puppycrawl.tools.checkstyle.checks.blocks;
public class InputNeedBracesEmptyDefault {
int value;
private void main() {
switch (value) {
default:
}
}
private void main1() {
switch (value) {
case 1:
}
}
}
@interface Example {
String priority() default "value";
}