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 @@

AvoidNestedBlocks

Description

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;
+        }
+}
+
+ + +

Properties

+ + + + + + + + + + + + + +
namedescriptiontypedefault value
allowInSwitchCaseAllow nested blocks in case statementsbooleanfalse
+

Examples

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 @@

  • Added excludes property to AvoidStarImport, contributed by Bill Schneider (request 744955).
  • - +
  • Added CyclomaticComplexityCheck from Simon Harris.
  • Added check to catch equality comparison with string literals using the == operator (module StringLiteralEquality, request 754835).
  • - +
  • Added check for definition of covariant equals() method - without overriding method equals(comp.lang.Object) + without overriding method equals(comp.lang.Object) (module coding.CovariantEquals).
  • Added NestedTryDepthCheck and @@ -104,6 +104,9 @@
  • Added IllegalTokenCheck from Simon Harris (request 750755).
  • +
  • Added allowInSwitchCase property to AvoidNestedBlocksCheck + to allow limiting the scope of variables to one case of a switch statement.
  • +

    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); }