From f1dced161ab0c818f0e1e125fc5b88b71f5b171e Mon Sep 17 00:00:00 2001 From: Andrei Selkin Date: Wed, 29 Jul 2015 17:23:06 +0300 Subject: [PATCH] Add new option for RightCurlyCheck, issue #1019. --- .../LeftCurlyRightCurlyTest.java | 3 + .../checks/blocks/RightCurlyCheck.java | 75 +++++-- .../checks/blocks/RightCurlyOption.java | 23 +- .../checks/blocks/RightCurlyCheckTest.java | 95 +++++++- .../InputRightCurlyAloneOrSingleline.java | 179 +++++++++++++++ .../InputRightCurlyAnnotations.java | 209 +++++++++++++++++- src/xdocs/property_types.xml | 19 ++ 7 files changed, 570 insertions(+), 33 deletions(-) create mode 100644 src/test/resources/com/puppycrawl/tools/checkstyle/InputRightCurlyAloneOrSingleline.java diff --git a/src/it/java/com/google/checkstyle/test/chapter4formatting/rule412nonemptyblocks/LeftCurlyRightCurlyTest.java b/src/it/java/com/google/checkstyle/test/chapter4formatting/rule412nonemptyblocks/LeftCurlyRightCurlyTest.java index b89b3acf8..e2cfd1cb1 100644 --- a/src/it/java/com/google/checkstyle/test/chapter4formatting/rule412nonemptyblocks/LeftCurlyRightCurlyTest.java +++ b/src/it/java/com/google/checkstyle/test/chapter4formatting/rule412nonemptyblocks/LeftCurlyRightCurlyTest.java @@ -101,8 +101,11 @@ public class LeftCurlyRightCurlyTest extends BaseCheckTestSupport{ newCheckConfig.addAttribute("tokens", "CLASS_DEF, METHOD_DEF, CTOR_DEF"); String checkMessageNew = getCheckMessage(RightCurlyCheck.class, "line.new", "}"); + String checkMessageAlone = getCheckMessage(RightCurlyCheck.class, "line.alone", "}"); final String[] expected = { + "97:5: " + checkMessageAlone, "97:6: " + checkMessageNew, + "108:5: " + checkMessageAlone, "108:6: " + checkMessageNew, "122:6: " + checkMessageNew, }; diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/blocks/RightCurlyCheck.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/blocks/RightCurlyCheck.java index c823005ff..3e9b2e397 100644 --- a/src/main/java/com/puppycrawl/tools/checkstyle/checks/blocks/RightCurlyCheck.java +++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/blocks/RightCurlyCheck.java @@ -19,8 +19,10 @@ package com.puppycrawl.tools.checkstyle.checks.blocks; +import com.puppycrawl.tools.checkstyle.ScopeUtils; import com.puppycrawl.tools.checkstyle.Utils; import com.puppycrawl.tools.checkstyle.api.DetailAST; +import com.puppycrawl.tools.checkstyle.api.Scope; import com.puppycrawl.tools.checkstyle.api.TokenTypes; import com.puppycrawl.tools.checkstyle.checks.AbstractOptionCheck; import com.puppycrawl.tools.checkstyle.checks.CheckUtils; @@ -69,6 +71,7 @@ import com.puppycrawl.tools.checkstyle.checks.CheckUtils; * @author lkuehne * @author o_sukhodolsky * @author maxvetrenko + * @author Andrei Selkin */ public class RightCurlyCheck extends AbstractOptionCheck { /** @@ -156,17 +159,6 @@ public class RightCurlyCheck extends AbstractOptionCheck { final DetailAST lcurly = details.lcurly; validate(details, rcurly, lcurly); - - if (!shouldStartLine) { - return; - } - final boolean startsLine = - Utils.whitespaceBefore(rcurly.getColumnNo(), - getLines()[rcurly.getLineNo() - 1]); - - if (!startsLine && lcurly.getLineNo() != rcurly.getLineNo()) { - log(rcurly, MSG_KEY_LINE_NEW, "}"); - } } /** @@ -183,8 +175,7 @@ public class RightCurlyCheck extends AbstractOptionCheck { && !hasLineBreakBefore(rcurly)) { log(rcurly, MSG_KEY_LINE_BREAK_BEFORE); } - - if (shouldCheckLastRcurly) { + else if (shouldCheckLastRcurly) { if (rcurly.getLineNo() == nextToken.getLineNo()) { log(rcurly, MSG_KEY_LINE_ALONE, "}"); } @@ -194,10 +185,62 @@ public class RightCurlyCheck extends AbstractOptionCheck { log(rcurly, MSG_KEY_LINE_SAME, "}"); } else if (getAbstractOption() == RightCurlyOption.ALONE - && rcurly.getLineNo() == nextToken.getLineNo() + && !isAloneOnLine(details) && !isEmptyBody(lcurly)) { log(rcurly, MSG_KEY_LINE_ALONE, "}"); } + else if (getAbstractOption() == RightCurlyOption.ALONE_OR_SINGLELINE + && !isAloneOnLine(details) + && !isSingleLineBlock(details) + && !isAnonInnerClassInit(lcurly) + && !isEmptyBody(lcurly)) { + log(rcurly, MSG_KEY_LINE_ALONE, "}"); + } + else if (shouldStartLine) { + final boolean startsLine = + Utils.whitespaceBefore(rcurly.getColumnNo(), + getLines()[rcurly.getLineNo() - 1]); + + if (!startsLine && lcurly.getLineNo() != rcurly.getLineNo()) { + log(rcurly, MSG_KEY_LINE_NEW, "}"); + } + } + } + + /** + * Checks whether right curly is alone on a line. + * @param details for validation. + * @return true if right curly is alone on a line. + */ + private static boolean isAloneOnLine(Details details) { + final DetailAST rcurly = details.rcurly; + final DetailAST lcurly = details.lcurly; + final DetailAST nextToken = details.nextToken; + return rcurly.getLineNo() != lcurly.getLineNo() + && rcurly.getLineNo() != nextToken.getLineNo(); + } + + /** + * Checks whether block has a single-line format. + * @param details for validation. + * @return true if block has single-line format. + */ + private static boolean isSingleLineBlock(Details details) { + final DetailAST rcurly = details.rcurly; + final DetailAST lcurly = details.lcurly; + final DetailAST nextToken = details.nextToken; + return rcurly.getLineNo() == lcurly.getLineNo() + && rcurly.getLineNo() != nextToken.getLineNo(); + } + + /** + * Checks wthether lcurly is in anonymous inner class initialization. + * @param lcurly left curly token. + * @return true if lcurly begins anonymous inner class initialization. + */ + private static boolean isAnonInnerClassInit(DetailAST lcurly) { + final Scope surroundingScope = ScopeUtils.getSurroundingScope(lcurly); + return surroundingScope.ordinal() == Scope.ANONINNER.ordinal(); } /** @@ -258,7 +301,7 @@ public class RightCurlyCheck extends AbstractOptionCheck { case TokenTypes.INSTANCE_INIT: lcurly = ast.findFirstToken(TokenTypes.SLIST); rcurly = lcurly.getLastChild(); - nextToken = ast; + nextToken = getNextToken(ast); break; default: // ATTENTION! We have default here, but we expect case TokenTypes.METHOD_DEF, @@ -272,7 +315,7 @@ public class RightCurlyCheck extends AbstractOptionCheck { // and code like "while(true);" rcurly = lcurly.getLastChild(); } - nextToken = lcurly; + nextToken = getNextToken(ast); break; } diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/blocks/RightCurlyOption.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/blocks/RightCurlyOption.java index a99e73675..1c8e6ca50 100644 --- a/src/main/java/com/puppycrawl/tools/checkstyle/checks/blocks/RightCurlyOption.java +++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/blocks/RightCurlyOption.java @@ -25,9 +25,28 @@ package com.puppycrawl.tools.checkstyle.checks.blocks; * @author Oliver Burn */ public enum RightCurlyOption { + /** - * Represents the policy that the brace must be alone on the line. For - * example: + * Represents the policy that the brace must be alone on the line + * and allows single-line format of block. + * For example: + * + *
+     * //Brace is alone on the line
+     * try {
+     * ...
+     * }
+     * inally {
+     *
+     * // Single-line format of block
+     * private int foo() { return 1; }
+     * 
+ **/ + ALONE_OR_SINGLELINE, + + /** + * Represents the policy that the brace must be alone on the line. + * For example: * *
      * try {
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/checks/blocks/RightCurlyCheckTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/checks/blocks/RightCurlyCheckTest.java
index 29321ddcf..72946ca72 100644
--- a/src/test/java/com/puppycrawl/tools/checkstyle/checks/blocks/RightCurlyCheckTest.java
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/checks/blocks/RightCurlyCheckTest.java
@@ -45,8 +45,6 @@ public class RightCurlyCheckTest extends BaseCheckTestSupport {
             "28:17: " + getCheckMessage(MSG_KEY_LINE_SAME, "}"),
             "40:13: " + getCheckMessage(MSG_KEY_LINE_SAME, "}"),
             "44:13: " + getCheckMessage(MSG_KEY_LINE_SAME, "}"),
-            "93:27: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
-            "93:27: " + getCheckMessage(MSG_KEY_LINE_NEW, "}"),
             "93:27: " + getCheckMessage(MSG_KEY_LINE_BREAK_BEFORE, "}"),
             "97:54: " + getCheckMessage(MSG_KEY_LINE_BREAK_BEFORE, "}"),
         };
@@ -61,8 +59,6 @@ public class RightCurlyCheckTest extends BaseCheckTestSupport {
             "28:17: " + getCheckMessage(MSG_KEY_LINE_SAME, "}"),
             "40:13: " + getCheckMessage(MSG_KEY_LINE_SAME, "}"),
             "44:13: " + getCheckMessage(MSG_KEY_LINE_SAME, "}"),
-            "93:27: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
-            "93:27: " + getCheckMessage(MSG_KEY_LINE_NEW, "}"),
             "93:27: " + getCheckMessage(MSG_KEY_LINE_BREAK_BEFORE, "}"),
             "97:54: " + getCheckMessage(MSG_KEY_LINE_BREAK_BEFORE, "}"),
         };
@@ -74,7 +70,6 @@ public class RightCurlyCheckTest extends BaseCheckTestSupport {
         checkConfig.addAttribute("option", RightCurlyOption.ALONE.toString());
         final String[] expected = {
             "93:27: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
-            "93:27: " + getCheckMessage(MSG_KEY_LINE_NEW, "}"),
         };
         verify(checkConfig, getPath("InputLeftCurlyOther.java"), expected);
     }
@@ -84,7 +79,9 @@ public class RightCurlyCheckTest extends BaseCheckTestSupport {
         checkConfig.addAttribute("option", RightCurlyOption.ALONE.toString());
         checkConfig.addAttribute("tokens", "CLASS_DEF, METHOD_DEF, CTOR_DEF");
         final String[] expected = {
+            "111:9: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
             "111:10: " + getCheckMessage(MSG_KEY_LINE_NEW, "}"),
+            "122:9: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
             "122:10: " + getCheckMessage(MSG_KEY_LINE_NEW, "}"),
             "136:10: " + getCheckMessage(MSG_KEY_LINE_NEW, "}"),
         };
@@ -147,14 +144,96 @@ public class RightCurlyCheckTest extends BaseCheckTestSupport {
     @Test
     public void testWithAnnotations() throws Exception {
         checkConfig.addAttribute("option", RightCurlyOption.ALONE.toString());
-        checkConfig.addAttribute("tokens", "CLASS_DEF, METHOD_DEF, CTOR_DEF, LITERAL_FOR, LITERAL_WHILE, LITERAL_DO, STATIC_INIT, INSTANCE_INIT");
+        checkConfig.addAttribute("tokens", "LITERAL_TRY, LITERAL_CATCH, LITERAL_FINALLY, LITERAL_IF, "
+            + "LITERAL_ELSE, CLASS_DEF, METHOD_DEF, CTOR_DEF, LITERAL_FOR, LITERAL_WHILE, LITERAL_DO, "
+            + "STATIC_INIT, INSTANCE_INIT");
         final String[] expected = {
-            "9:57: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
-            "16:41: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "9:77: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "12:65: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "23:46: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "27:31: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "30:35: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "33:36: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "39:73: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "41:37: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "46:58: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "48:97: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "51:30: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "54:30: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "61:38: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "68:62: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "77:28: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "79:21: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "81:20: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "83:14: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "94:26: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "104:29: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "108:29: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "112:52: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "112:112: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "115:18: " + getCheckMessage(MSG_KEY_LINE_NEW, "}"),
+            "119:23: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "122:37: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "124:30: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "128:77: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "137:9: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "139:9: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "149:9: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "151:75: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "152:77: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "152:93: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "153:77: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "154:77: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "154:93: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "160:37: " + getCheckMessage(MSG_KEY_LINE_NEW, "}"),
+            "167:37: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "182:9: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "189:9: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "189:13: " + getCheckMessage(MSG_KEY_LINE_NEW, "}"),
+            "198:9: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "198:10: " + getCheckMessage(MSG_KEY_LINE_NEW, "}"),
+            "202:49: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "202:50: " + getCheckMessage(MSG_KEY_LINE_NEW, "}"),
+            "205:75: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "205:76: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "205:77: " + getCheckMessage(MSG_KEY_LINE_NEW, "}"),
+            "209:76: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "217:27: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+
         };
         verify(checkConfig, getPath("InputRightCurlyAnnotations.java"), expected);
     }
 
+    @Test
+    public void testAloneOrSingleLine() throws Exception {
+        checkConfig.addAttribute("option", RightCurlyOption.ALONE_OR_SINGLELINE.toString());
+        checkConfig.addAttribute("tokens", "LITERAL_TRY, LITERAL_CATCH, LITERAL_FINALLY, LITERAL_IF, "
+            + "LITERAL_ELSE, CLASS_DEF, METHOD_DEF, CTOR_DEF, LITERAL_FOR, LITERAL_WHILE, LITERAL_DO, "
+            + "STATIC_INIT, INSTANCE_INIT");
+        final String[] expected = {
+            "60:26: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "69:29: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "74:52: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "77:18: " + getCheckMessage(MSG_KEY_LINE_NEW, "}"),
+            "85:30: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "97:9: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "99:9: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "119:37: " + getCheckMessage(MSG_KEY_LINE_NEW, "}"),
+            "126:37: " + getCheckMessage(MSG_KEY_LINE_NEW, "}"),
+            "148:13: " + getCheckMessage(MSG_KEY_LINE_NEW, "}"),
+            "157:9: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "157:10: " + getCheckMessage(MSG_KEY_LINE_NEW, "}"),
+            "161:49: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "161:50: " + getCheckMessage(MSG_KEY_LINE_NEW, "}"),
+            "164:75: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "164:76: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+            "164:77: " + getCheckMessage(MSG_KEY_LINE_NEW, "}"),
+            "176:27: " + getCheckMessage(MSG_KEY_LINE_ALONE, "}"),
+
+        };
+        verify(checkConfig, getPath("InputRightCurlyAloneOrSingleline.java"), expected);
+    }
+
     @Test
     public void testCatchWithoutFinally() throws Exception {
         final String[] expected = {
diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/InputRightCurlyAloneOrSingleline.java b/src/test/resources/com/puppycrawl/tools/checkstyle/InputRightCurlyAloneOrSingleline.java
new file mode 100644
index 000000000..9e719ebce
--- /dev/null
+++ b/src/test/resources/com/puppycrawl/tools/checkstyle/InputRightCurlyAloneOrSingleline.java
@@ -0,0 +1,179 @@
+package com.puppycrawl.tools.checkstyle;
+
+public class InputRightCurlyAloneOrSingleline {
+
+    public boolean equals(Object other) { boolean flag = true; return flag; } 
+
+    public int hashCode()
+    { 
+        int a = 10;
+        return 1;
+    }
+
+    private void foo()
+    { int var1 = 5; var2 = 6; } 
+
+    private void foo1() { return; } 
+
+    private String foo2() { return toString();
+    } 
+
+    private void foo3() { ; return; } 
+
+    private int var1;
+    private int var2;
+    public InputRightCurlyAloneOrSingleline() { this.var1 = 1; } 
+    public InputRightCurlyAloneOrSingleline(int var1, int var2) { this.var1 = var1; this.var2 = var2; } 
+
+    private void foo4() { ;; } 
+
+    private void foo5() { ; } 
+
+    private void foo6() {  } 
+
+    private void foo12() {
+        try { int i = 5; int b = 10; } 
+        catch (Exception e) { } 
+    } 
+
+    private void foo13() {
+        for (int i = 0; i < 10; i++) { int a = 5; int b = 6; } 
+
+        do
+        {
+            var1 = 2;
+        } 
+        while (var2 == 2);
+    } 
+
+    static { int a; int b; } 
+
+    { int c; int d;} 
+
+    private void foo14() {
+        if (var1 > 0) {
+            return;
+        } 
+    } 
+
+    private void foo15() {
+        class A { int a; } var1++; //violation
+        class B {  } 
+        if(true) {
+
+        } 
+        else;
+    }
+
+    private void foo16() {
+        if (true) { return; } else { } //violation
+        if (false) {
+        }
+    }
+
+    private void foo17() { int var1 = 5; var2 = 6; } private void foo18() {int var1 = 5; var2 = 6; } //violation
+
+    private void foo19() {int var1 = 5;
+        var2 = 6;} //violation
+
+    private String foo20() {
+        do { var2 ++; }  
+        while (var2 < 15);
+
+        while (var1 < 10) { var1++; } 
+
+        do { var2++; var1++; } while (var2 < 15); return ""+0xCAFEBABE; //violation
+    }
+
+    private void foo21() {
+        new Object() { @Override protected void finalize() { "".toString(); }}; 
+    } 
+
+    void foo22() {
+        long startTime = System.nanoTime();
+        try {
+            int a = 5;
+            toString();
+        } catch (Exception e) { //violation
+            throw new RuntimeException(e);
+        } finally { toString(); } //violation
+    }
+
+    void doDoubleBraceInitialization() {
+        java.util.Map map = new java.util.LinkedHashMap() {{
+            put("Hello", "World");
+            put("first", "second");
+            put("polygene", "lubricants");
+            put("alpha", "betical");
+        }}; // it's ok
+
+        Thread t = new Thread() {@Override public void run() {super.run();}};
+        new Object() { @Override protected void finalize() { "".toString(); }  { int a = 5; }};
+        new Object() { @Override protected void finalize() { "".toString(); }  int b = 10; };
+        new Object() { @Override protected void finalize() { "".toString(); }  { int c = 5; } int d = 8; };
+
+        java.util.Map map2 = new java.util.LinkedHashMap() {{
+            put("Hello", "World");
+            put("first", "second");
+            put("polygene", "lubricants");
+            put("alpha", "betical");}  //violation
+        };
+
+        java.util.Map map3 = new java.util.LinkedHashMap() {{
+            put("Hello", "World");
+            put("first", "second");
+            put("polygene", "lubricants");
+            put("alpha", "betical");}}; //violation
+
+        java.util.Map map4 = new java.util.LinkedHashMap() {{
+            put("Hello", "World");
+            put("first", "second");
+            put("polygene", "lubricants");
+            put("alpha", "betical");
+        }
+        };
+
+        foo23(new java.util.HashSet() {{
+            add("XZ13s");
+            add("AB21/X");
+            add("YYLEX");
+            add("AR5E");
+        }});  //it's ok, can't be formatted better
+
+        foo23(new java.util.HashSet() {{
+            add("XZ13s");
+            add("AB21/X");
+            add("YYLEX");
+            add("AR5E");
+        }});} //violation
+
+
+    void foo23(java.util.HashSet set) {
+    }
+
+    void foo25() {
+        for (int i = 0; i < 10; i++) {
+            System.out.println("Hello, world!");
+        }} //violation
+
+    void foo26() {
+        for (int i = 0; i < 10; i++) {
+            System.out.println("Hello, world!");}} //violation
+
+    void foo27() {
+        for (int i = 0; i < 10; i++) {for (int j = 0; j < 15; j++) {int a;}}} //violation
+
+    private java.util.ArrayList foo28(int delta) {
+        return new java.util.ArrayList() {
+            @Override public int size() { return Math.max(0, super.size() + 1);};
+        };
+    }
+
+    private void foo29() {
+        boolean flag = true;
+        if (flag) {
+            System.out.println("heh");
+            flag = !flag; } System.err. //violation
+            println("Xe-xe");
+    }
+}
diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/InputRightCurlyAnnotations.java b/src/test/resources/com/puppycrawl/tools/checkstyle/InputRightCurlyAnnotations.java
index 4baa5a61b..16de3f41d 100644
--- a/src/test/resources/com/puppycrawl/tools/checkstyle/InputRightCurlyAnnotations.java
+++ b/src/test/resources/com/puppycrawl/tools/checkstyle/InputRightCurlyAnnotations.java
@@ -3,17 +3,13 @@ package com.puppycrawl.tools.checkstyle;
 @TestClassAnnotation
 class InputRightCurlyAnnotations
 {
-    private static final int X = 10;
+
     @Deprecated
     @Override
-    public boolean equals(Object other) { return false; }
+    public boolean equals(Object other) { boolean flag = true; return flag; } //violation
 
     @Override
-    public String toString() {
-        return "InputRightCurlyAnnotations{}";
-    }
-
-    public String foo() { return "foo"; }
+    public String toString() { String s = "toString"; return s; } //violation
 
     @Override
     @SuppressWarnings("unused")
@@ -22,4 +18,203 @@ class InputRightCurlyAnnotations
         int a = 10;
         return 1;
     }
+
+    @SuppressWarnings("unused")
+    private void foo2() { int a = 9; return; } //violation
+
+    @SuppressWarnings("unused")
+    private void foo3()
+    { int var1 = 5; var2 = 6; } //violation
+
+    @Deprecated
+    private void foo4() { return; } //violation
+
+    @SuppressWarnings("unused")
+    private int foo5() { return 1; } //violation
+
+    @SuppressWarnings("unused")
+    private String foo6() { return toString();
+    }
+
+    private String foo7() { String s = toString(); return s.toString(); } //violation
+
+    private void foo8() { ; return; } //violation
+
+    private int var1;
+    private int var2;
+    @SuppressWarnings("unused")
+    public InputRightCurlyAnnotations() { this.var1 = 1; } //violation
+    @SuppressWarnings("unused")
+    public InputRightCurlyAnnotations(int var1, int var2) { this.var1 = var1; this.var2 = var2; } //violation
+
+    @SuppressWarnings("unused")
+    private void foo9() { ;; } //violation
+
+    @SuppressWarnings("unused")
+    private void foo10() { ; } //violation
+
+    @SuppressWarnings("unused")
+    private void foo11() {  } //it's ok - empty block
+
+    @SuppressWarnings("unused")
+    private void foo12() {
+        try { int i = 5; int b = 10; } //violation
+        catch (Exception e) { } //it's ok - empty block
+    }
+
+    @Deprecated
+    @SuppressWarnings("unused")
+    private void foo13() {
+        for (int i = 0; i < 10; i++) { int a = 5; int b = 6; } //violation
+
+        do
+        {
+            var1 = 2;
+        }
+        while (var2 == 2);
+    }
+
+    static { int a; int b; } //violation
+
+    static { int a; } //violation
+
+    { int c; int d;} //violation
+
+    { int c; } //violation
+
+    @Deprecated
+    private void foo14() {
+        if (var1 > 0) {
+            return;
+        }
+    }
+
+    @Deprecated
+    private void foo15() {
+        class A { int a; } var1++; //violation
+        class B {  }
+        if(true) {
+
+        }
+        else;
+    }
+
+    @Deprecated
+    private void foo16() {
+        if (true) { return; } else { } //violation
+        if (false) {
+        }
+
+        if (true) { return; } else { } //violation
+    }
+
+    @Deprecated
+    private void foo17() { int var1 = 5; var2 = 6; } @Deprecated private void foo18() {int var1 = 5; var2 = 6; } //violation
+
+    private void foo19() {int var1 = 5;
+        var2 = 6;} //violation
+
+    @SuppressWarnings("Hello, world!")
+    private String foo20() {
+        do { var2 ++; } //violation
+        while (var2 < 15);
+
+        while (var1 < 10) { var1++; } //violation
+
+        do { var2++; var1++; } while (var2 < 15); return ""+0xCAFEBABE; //violation
+    }
+
+    private void foo21() {
+        new Object() { @Override protected void finalize() { "".toString(); }}; //violation
+    }
+
+    @SuppressWarnings("All")
+    void foo22() {
+        long startTime = System.nanoTime();
+        try {
+            int a = 5;
+            toString();
+        } catch (Exception e) { //violation
+            throw new RuntimeException(e);
+        } finally { toString(); } //violation
+    }
+
+    @SuppressWarnings("")
+    void doDoubleBraceInitialization() {
+        java.util.Map map = new java.util.LinkedHashMap() {{
+            put("Hello", "World");
+            put("first", "second");
+            put("polygene", "lubricants");
+            put("alpha", "betical");
+        }}; //violation
+
+        Thread t = new Thread() {@Override public void run() {super.run();}}; //violation
+        new Object() { @Override protected void finalize() { "".toString(); }  { int a = 5; }}; //violation
+        new Object() { @Override protected void finalize() { "".toString(); }  int b = 10; }; //violation
+        new Object() { @Override protected void finalize() { "".toString(); }  { int c = 5; } int d = 8; }; //violation
+
+        java.util.Map map2 = new java.util.LinkedHashMap() {{
+            put("Hello", "World");
+            put("first", "second");
+            put("polygene", "lubricants");
+            put("alpha", "betical");}  //violation
+        };
+
+        java.util.Map map3 = new java.util.LinkedHashMap() {{
+            put("Hello", "World");
+            put("first", "second");
+            put("polygene", "lubricants");
+            put("alpha", "betical");}};  //violation
+
+        java.util.Map map4 = new java.util.LinkedHashMap() {{
+            put("Hello", "World");
+            put("first", "second");
+            put("polygene", "lubricants");
+            put("alpha", "betical");
+            }
+        };
+
+        foo23(new java.util.HashSet() {{
+            add("XZ13s");
+            add("AB21/X");
+            add("YYLEX");
+            add("AR5E");
+        }}); //violation
+
+        foo23(new java.util.HashSet() {{
+            add("XZ13s");
+            add("AB21/X");
+            add("YYLEX");
+            add("AR5E");
+        }});} //violation
+
+
+    void foo23(java.util.HashSet set) {
+    }
+
+    void foo25() {
+        for (int i = 0; i < 10; i++) {
+            System.out.println("Hello, world!");
+        }} //violation
+
+    void foo26() {
+        for (int i = 0; i < 10; i++) {
+            System.out.println("Hello, world!");}} //violation
+
+    void foo27() {
+        for (int i = 0; i < 10; i++) {for (int j = 0; j < 15; j++) {int a;}}} //violation
+
+    private java.util.ArrayList foo28(int delta) {
+        return new java.util.ArrayList() {
+        @Override public int size() { return Math.max(0, super.size() + 1);}; //violation
+        };
+    }
+
+    private void foo29() {
+        boolean flag = true;
+        if (flag) {
+            System.out.println("heh");
+            flag = !flag; } System.err. //violation
+            println("Xe-xe");
+    }
 }
diff --git a/src/xdocs/property_types.xml b/src/xdocs/property_types.xml
index 7c2a23d92..01f74af6e 100644
--- a/src/xdocs/property_types.xml
+++ b/src/xdocs/property_types.xml
@@ -307,6 +307,25 @@
             
+ + + alone_or_singleline + + The brace must be alone on the line, yet + single-line format of block is allowed. + For example: +
+    // Brace is alone on the line
+    try {
+    ...
+    }
+    finally {
+
+    // Single-line format of block
+    private int foo() { return 1; }
+                  
+ +