diff --git a/docs/config_blocks.html b/docs/config_blocks.html index 4ccc15610..c140eadf9 100644 --- a/docs/config_blocks.html +++ b/docs/config_blocks.html @@ -325,22 +325,13 @@
Finds nested blocks, i.e. blocks that are used freely in the code. - For example this Check finds the obsolete braces in -
-
- switch (a)
- {
- case 0:
- {
- x = 1;
- }
- break;
- default:
- break;
- }
-
- and flags confusing code like + Rationale: Nested blocks are often leftovers from the debugging process, + they confuse the reader. +
+ ++ For example this Check finds the obsolete braces in
public void guessTheOutput() @@ -353,9 +344,67 @@ }
- Rationale: Nested blocks are often leftovers from the debugging process, they confuse - the reader. + and debugging / refactoring leftovers such as
+ +
+// if (conditionThatIsNotUsedAnyLonger)
+{
+ System.out.println("unconditional");
+}
+
+
+ + A case in a switch statement does not implicitly form a block. + Thus to be able to introduce local variables that have case scope + it is necessary to open a nested block. This is supported, set + the allowInSwitchCase property to true and include all statements + of the case in the block. +
+ +
+switch (a)
+{
+ case 0:
+ // Never OK, break outside block
+ {
+ x = 1;
+ }
+ break;
+ case 1:
+ // Never OK, statement outside block
+ System.out.println("Hello");
+ {
+ x = 2;
+ break;
+ }
+ case 1:
+ // OK if allowInSwitchCase is true
+ {
+ System.out.println("Hello");
+ x = 2;
+ break;
+ }
+}
+
+
+
+ | name | +description | +type | +default value | +
|---|---|---|---|
| allowInSwitchCase | +Allow nested blocks in case statements | +boolean | +false | +
To configure the check: diff --git a/docs/releasenotes.html b/docs/releasenotes.html index bc3ec3820..248377052 100644 --- a/docs/releasenotes.html +++ b/docs/releasenotes.html @@ -87,14 +87,14 @@
diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/blocks/AvoidNestedBlocksCheck.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/blocks/AvoidNestedBlocksCheck.java index f5469b8f7..fc84ceb68 100644 --- a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/blocks/AvoidNestedBlocksCheck.java +++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/blocks/AvoidNestedBlocksCheck.java @@ -24,20 +24,9 @@ import com.puppycrawl.tools.checkstyle.api.DetailAST; /** * Finds nested blocks. - * For example this Check finds the obsolete braces in - *
- * switch (a)
- * {
- * case 0:
- * {
- * x = 1;
- * }
- * break;
- * default:
- * break;
- * }
- *
- * and flags confusing code like
+ *
+ * + * For example this Check flags confusing code like *
* public void guessTheOutput()
* {
@@ -49,10 +38,59 @@ import com.puppycrawl.tools.checkstyle.api.DetailAST;
* }
*
*
+ * and debugging / refactoring leftovers such as
+ *
+ *
+ * // if (someOldCondition)
+ * {
+ * System.out.println("unconditional");
+ * }
+ *
+ *
+ * + * A case in a switch statement does not implicitly form a block. + * Thus to be able to introduce local variables that have case scope + * it is necessary to open a nested block. This is supported, set + * the allowInSwitchCase property to true and include all statements + * of the case in the block. + *
+ * + *
+ * switch (a)
+ * {
+ * case 0:
+ * // Never OK, break outside block
+ * {
+ * x = 1;
+ * }
+ * break;
+ * case 1:
+ * // Never OK, statement outside block
+ * System.out.println("Hello");
+ * {
+ * x = 2;
+ * break;
+ * }
+ * case 1:
+ * // OK if allowInSwitchCase is true
+ * {
+ * System.out.println("Hello");
+ * x = 2;
+ * break;
+ * }
+ * }
+ *
+ *
* @author lkuehne
*/
public class AvoidNestedBlocksCheck extends Check
{
+ /**
+ * Whether nested blocks are allowed if they are the
+ * only child of a switch case.
+ */
+ private boolean mAllowInSwitchCase = false;
+
/** @see Check */
public int[] getDefaultTokens()
{
@@ -62,9 +100,20 @@ public class AvoidNestedBlocksCheck extends Check
/** @see Check */
public void visitToken(DetailAST aAST)
{
- if (aAST.getParent().getType() == TokenTypes.SLIST) {
+ final DetailAST parent = aAST.getParent();
+ if (parent.getType() == TokenTypes.SLIST) {
+ if (mAllowInSwitchCase
+ && parent.getParent().getType() == TokenTypes.CASE_GROUP
+ && parent.getNumberOfChildren() == 1)
+ {
+ return;
+ }
log(aAST.getLineNo(), aAST.getColumnNo(), "block.nested");
}
}
+ public void setAllowInSwitchCase(boolean aAllowInSwitchCase)
+ {
+ mAllowInSwitchCase = aAllowInSwitchCase;
+ }
}
diff --git a/src/tests/com/puppycrawl/tools/checkstyle/checks/blocks/AvoidNestedBlocksCheckTest.java b/src/tests/com/puppycrawl/tools/checkstyle/checks/blocks/AvoidNestedBlocksCheckTest.java
index 0c73157e1..be2b78b52 100644
--- a/src/tests/com/puppycrawl/tools/checkstyle/checks/blocks/AvoidNestedBlocksCheckTest.java
+++ b/src/tests/com/puppycrawl/tools/checkstyle/checks/blocks/AvoidNestedBlocksCheckTest.java
@@ -6,14 +6,31 @@ import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
public class AvoidNestedBlocksCheckTest
extends BaseCheckTestCase
{
- public void testIt()
+ public void testStrictSettings()
throws Exception
{
final DefaultConfiguration checkConfig =
createCheckConfig(AvoidNestedBlocksCheck.class);
final String[] expected = {
"22:9: Avoid nested blocks.",
- "38:17: Avoid nested blocks.",
+ "44:17: Avoid nested blocks.",
+ "50:17: Avoid nested blocks.",
+ "58:17: Avoid nested blocks.",
+ };
+ verify(checkConfig, getPath("InputNestedBlocks.java"), expected);
+ }
+
+ public void testAllowSwitchInCase()
+ throws Exception
+ {
+ final DefaultConfiguration checkConfig =
+ createCheckConfig(AvoidNestedBlocksCheck.class);
+ checkConfig.addAttribute("allowInSwitchCase", Boolean.TRUE.toString());
+
+ final String[] expected = {
+ "22:9: Avoid nested blocks.",
+ "44:17: Avoid nested blocks.",
+ "58:17: Avoid nested blocks.",
};
verify(checkConfig, getPath("InputNestedBlocks.java"), expected);
}