From bd6f9bcb046a2dc66486adf4f94e780f5b939890 Mon Sep 17 00:00:00 2001 From: Piyush Sharma Date: Mon, 6 Mar 2017 05:58:02 +0530 Subject: [PATCH] Issue #3839: Added 3 methods to help detect empty LITERAL_CASE. Added corresponding UTs --- .../checks/blocks/EmptyBlockCheck.java | 72 +++++++++++++++++++ .../checks/blocks/EmptyBlockCheckTest.java | 32 +++++++++ .../checks/blocks/InputEmptyCase.java | 36 ++++++++++ 3 files changed, 140 insertions(+) create mode 100644 src/test/resources/com/puppycrawl/tools/checkstyle/checks/blocks/InputEmptyCase.java diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/blocks/EmptyBlockCheck.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/blocks/EmptyBlockCheck.java index cbd9cf385859..f112606d91f7 100644 --- a/src/main/java/com/puppycrawl/tools/checkstyle/checks/blocks/EmptyBlockCheck.java +++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/blocks/EmptyBlockCheck.java @@ -171,6 +171,10 @@ else if (!hasText(leftCurly)) { ast.getText()); } } + + if (ast.getType() == TokenTypes.LITERAL_CASE) { + checkForEmptyCase(ast); + } } /** @@ -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; + } + } diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/checks/blocks/EmptyBlockCheckTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/checks/blocks/EmptyBlockCheckTest.java index deb792ac48a3..baee36acb42b 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/checks/blocks/EmptyBlockCheckTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/checks/blocks/EmptyBlockCheckTest.java @@ -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); + } } diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/checks/blocks/InputEmptyCase.java b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/blocks/InputEmptyCase.java new file mode 100644 index 000000000000..28b4fcc15c87 --- /dev/null +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/blocks/InputEmptyCase.java @@ -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 + } + } + } +} \ No newline at end of file