From 89ee699fae396abf7706ecaa59e8dbe6c833a67d Mon Sep 17 00:00:00 2001 From: Oleg Sukhodolsky Date: Tue, 1 Nov 2005 15:38:32 +0000 Subject: [PATCH] Applied patch 906531 (WhitespaceAround allows empty method/ctor bodies.) Thanks to Eric Roe --- .../whitespace/WhitespaceAroundCheck.java | 110 +++++++++++++++++- .../tools/checkstyle/InputBraces.java | 6 + .../whitespace/WhitespaceAroundTest.java | 33 ++++-- src/xdocs/config_whitespace.xml | 24 +++- src/xdocs/releasenotes.xml | 6 + 5 files changed, 166 insertions(+), 13 deletions(-) diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/whitespace/WhitespaceAroundCheck.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/whitespace/WhitespaceAroundCheck.java index 8845fee5f..3b39e1588 100644 --- a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/whitespace/WhitespaceAroundCheck.java +++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/whitespace/WhitespaceAroundCheck.java @@ -95,13 +95,37 @@ import com.puppycrawl.tools.checkstyle.api.DetailAST; * value="ASSIGN,DIV_ASSIGN,PLUS_ASSIGN,MINUS_ASSIGN,STAR_ASSIGN,MOD_ASSIGN,SR_ASSIGN,BSR_ASSIGN,SL_ASSIGN,BXOR_ASSIGN,BOR_ASSIGN,BAND_ASSIGN"/> * </module> * + *

+ * In addition, this check can be configured to allow empty method and/or + * constructor bodies. For example, a method with an empty body might look + * like: + *

+ *

+ *

    public void doSomething(int val) {}
+ *

+ *

+ * To configure the check to allow empty method blocks use + *

+ *

+ *

   <property name="allowEmptyMethods" value="true" />
+ *

+ *

+ * To configure the check to allow empty constructor blocks use + *

+ *

+ *

   <property name="allowEmptyConstructors" value="true" />
+ *

* * @author Oliver Burn * @version 1.0 */ -public class WhitespaceAroundCheck - extends Check +public class WhitespaceAroundCheck extends Check { + /** Whether or not empty constructor bodies are allowed. */ + private boolean mAllowEmptyCtors; + /** Whether or not empty method bodies are allowed. */ + private boolean mAllowEmptyMethods; + /** {@inheritDoc} */ public int[] getDefaultTokens() { @@ -160,6 +184,24 @@ public class WhitespaceAroundCheck }; } + /** + * Sets whether or now empty method bodies are allowed. + * @param aAllow true to allow empty method bodies. + */ + public void setAllowEmptyMethods(boolean aAllow) + { + mAllowEmptyMethods = aAllow; + } + + /** + * Sets whether or now empty constructor bodies are allowed. + * @param aAllow true to allow empty constructor bodies. + */ + public void setAllowEmptyConstructors(boolean aAllow) + { + mAllowEmptyCtors = aAllow; + } + /** {@inheritDoc} */ public void visitToken(DetailAST aAST) { @@ -195,6 +237,13 @@ public class WhitespaceAroundCheck return; } + // Check for allowed empty method or ctor blocks. + if (emptyMethodBlockCheck(aAST, parentType) + || emptyCtorBlockCheck(aAST, parentType)) + { + return; + } + final String[] lines = getLines(); final String line = lines[aAST.getLineNo() - 1]; final int before = aAST.getColumnNo() - 1; @@ -227,4 +276,61 @@ public class WhitespaceAroundCheck new Object[] {aAST.getText()}); } } + + /** + * Test if the given DetailAST is part of an allowed empty + * method block. + * @param aAST the DetailAST to test. + * @param aParentType the token type of aAST's parent. + * @return true if aAST makes up part of an + * allowed empty method block. + */ + private boolean emptyMethodBlockCheck(DetailAST aAST, int aParentType) + { + return mAllowEmptyMethods + && emptyBlockCheck(aAST, aParentType, TokenTypes.METHOD_DEF); + } + + /** + * Test if the given DetailAST is part of an allowed empty + * constructor (ctor) block. + * @param aAST the DetailAST to test. + * @param aParentType the token type of aAST's parent. + * @return true if aAST makes up part of an + * allowed empty constructor block. + */ + private boolean emptyCtorBlockCheck(DetailAST aAST, int aParentType) + { + return mAllowEmptyCtors + && emptyBlockCheck(aAST, aParentType, TokenTypes.CTOR_DEF); + } + + /** + * Test if the given DetailAST is part of an empty block. + * An example empty block might look like the following + *

+ *

   public void myMethod(int val) {}
+ *

+ * In the above, the method body is an empty block ("{}"). + * + * @param aAST the DetailAST to test. + * @param aParentType the token type of aAST's parent. + * @param aMatch the parent token type we're looking to match. + * @return true if aAST makes up part of an + * empty block contained under a aMatch token type + * node. + */ + private boolean emptyBlockCheck(DetailAST aAST, int aParentType, int aMatch) + { + final int type = aAST.getType(); + if (type == TokenTypes.RCURLY) { + DetailAST grandParent = aAST.getParent().getParent(); + return aParentType == TokenTypes.SLIST + && grandParent.getType() == aMatch; + } + + return type == TokenTypes.SLIST + && aParentType == aMatch + && aAST.getFirstChild().getType() == TokenTypes.RCURLY; + } } diff --git a/src/testinputs/com/puppycrawl/tools/checkstyle/InputBraces.java b/src/testinputs/com/puppycrawl/tools/checkstyle/InputBraces.java index 0ae805388..762a5714d 100644 --- a/src/testinputs/com/puppycrawl/tools/checkstyle/InputBraces.java +++ b/src/testinputs/com/puppycrawl/tools/checkstyle/InputBraces.java @@ -110,4 +110,10 @@ class InputBraces for (;;) { } } + + /** Empty constructor block. **/ + public InputBraces() {} + + /** Empty method block. **/ + public void emptyImplementation() {} } diff --git a/src/tests/com/puppycrawl/tools/checkstyle/checks/whitespace/WhitespaceAroundTest.java b/src/tests/com/puppycrawl/tools/checkstyle/checks/whitespace/WhitespaceAroundTest.java index 5cb3f44fe..68a658c51 100644 --- a/src/tests/com/puppycrawl/tools/checkstyle/checks/whitespace/WhitespaceAroundTest.java +++ b/src/tests/com/puppycrawl/tools/checkstyle/checks/whitespace/WhitespaceAroundTest.java @@ -6,11 +6,16 @@ import com.puppycrawl.tools.checkstyle.DefaultConfiguration; public class WhitespaceAroundTest extends BaseCheckTestCase { + DefaultConfiguration checkConfig; + + public void setUp() + { + checkConfig = createCheckConfig(WhitespaceAroundCheck.class); + } + public void testIt() throws Exception { - final DefaultConfiguration checkConfig = - createCheckConfig(WhitespaceAroundCheck.class); final String[] expected = { "16:22: '=' is not preceded with whitespace.", "16:23: '=' is not followed by whitespace.", @@ -54,8 +59,6 @@ public class WhitespaceAroundTest public void testIt2() throws Exception { - final DefaultConfiguration checkConfig = - createCheckConfig(WhitespaceAroundCheck.class); final String[] expected = { "153:27: '=' is not followed by whitespace.", "154:27: '=' is not followed by whitespace.", @@ -70,13 +73,27 @@ public class WhitespaceAroundTest public void testIt3() throws Exception { - final DefaultConfiguration checkConfig = - createCheckConfig(WhitespaceAroundCheck.class); final String[] expected = { "41:14: 'while' is not followed by whitespace.", "58:12: 'for' is not followed by whitespace.", // + ":58:23: ';' is not followed by whitespace.", // + ":58:29: ';' is not followed by whitespace.", + "115:27: '{' is not followed by whitespace.", + "115:27: '}' is not preceded with whitespace.", + "118:40: '{' is not followed by whitespace.", + "118:40: '}' is not preceded with whitespace.", + }; + verify(checkConfig, getPath("InputBraces.java"), expected); + } + + public void testIt4() + throws Exception + { + checkConfig.addAttribute("allowEmptyMethods", "true"); + checkConfig.addAttribute("allowEmptyConstructors", "true"); + final String[] expected = { + "41:14: 'while' is not followed by whitespace.", + "58:12: 'for' is not followed by whitespace.", }; verify(checkConfig, getPath("InputBraces.java"), expected); } @@ -84,8 +101,6 @@ public class WhitespaceAroundTest public void testGenericsTokensAreFlagged() throws Exception { - final DefaultConfiguration checkConfig = - createCheckConfig(WhitespaceAroundCheck.class); final String[] expected = { "6:27: '<' is not preceded with whitespace.", "6:28: '<' is not followed by whitespace.", @@ -104,8 +119,6 @@ public class WhitespaceAroundTest public void test1322879() throws Exception { - final DefaultConfiguration checkConfig = - createCheckConfig(WhitespaceAroundCheck.class); final String[] expected = { }; verify(checkConfig, getPath("whitespace/InputWhitespaceAround.java"), diff --git a/src/xdocs/config_whitespace.xml b/src/xdocs/config_whitespace.xml index 78f35649e..0bcecf05b 100755 --- a/src/xdocs/config_whitespace.xml +++ b/src/xdocs/config_whitespace.xml @@ -899,7 +899,17 @@ for (Iterator foo = very.long.line.iterator();

- Checks that a token is surrounded by whitespace. + Checks that a token is surrounded by whitespace. Empty constructor and + method bodies (blocks) of the form +

+

+

public MyClass() {}      // empty constructor
+public void func() {}    // empty method
+

+

+ may optionally be exempted from the policy using the + allowEmptyMethods and allowEmptyConstructors + properties.

@@ -1021,6 +1031,18 @@ for (Iterator foo = very.long.line.iterator(); all tokens + + allowEmptyConstructors + allow empty constructor bodies + boolean + false + + + allowEmptyMethods + allow empty method bodies + boolean + false + diff --git a/src/xdocs/releasenotes.xml b/src/xdocs/releasenotes.xml index af24d371e..efc517244 100755 --- a/src/xdocs/releasenotes.xml +++ b/src/xdocs/releasenotes.xml @@ -40,6 +40,12 @@ FallThrough check now can check last case group (property checkLastCaseGroup, bug 1245942). +
  • + Applied patch 906531 (WhitespaceAround allows empty + method/ctor bodies.) Thanks to Eric Roe (module + WhitespaceAround, properties allowEmptyCtors and + allowEmptyMethods). +
  • Fixed Bugs: