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
- 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
+
+ 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();
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();Fixed Bugs: