diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/whitespace/EmptyLineSeparatorCheck.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/whitespace/EmptyLineSeparatorCheck.java new file mode 100644 index 000000000..d84813ff3 --- /dev/null +++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/whitespace/EmptyLineSeparatorCheck.java @@ -0,0 +1,171 @@ +//////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code for adherence to a set of rules. +// Copyright (C) 2001-2014 Oliver Burn +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//////////////////////////////////////////////////////////////////////////////// + +package com.puppycrawl.tools.checkstyle.checks.whitespace; + +import com.puppycrawl.tools.checkstyle.api.Check; +import com.puppycrawl.tools.checkstyle.api.DetailAST; +import com.puppycrawl.tools.checkstyle.api.TokenTypes; + +/** + * + * Checks for blank line separators after package, all import declarations, + * fields, constructors, methods, nested classes, + * static initializers and instance initializers. + * + *

By default the check will check the following statements: + * {@link TokenTypes#PACKAGE_DEF PACKAGE_DEF}, + * {@link TokenTypes#IMPORT IMPORT}, + * {@link TokenTypes#CLASS_DEF CLASS_DEF}, + * {@link TokenTypes#INTERFACE_DEF INTERFACE_DEF}, + * {@link TokenTypes#LSTATIC_INIT STATIC_INIT}, + * {@link TokenTypes#INSTANCE_INIT INSTANCE_INIT}, + * {@link TokenTypes#METHOD_DEF METHOD_DEF}, + * {@link TokenTypes#CTOR_DEF CTOR_DEF}, + * {@link TokenTypes#VARIABLE_DEF VARIABLE_DEF}. + *

+ * + *

+ * Example of declarations without blank line separator: + *

+ * + *
+ * package com.puppycrawl.tools.checkstyle.whitespace;
+ * import java.io.Serializable;
+ * class Foo
+ * {
+ *     public static final int FOO_CONST = 1;
+ *     public void foo() {} //should be separated from previous statement.
+ * }
+ * 
+ * + *

An example of how to configure the check with default parameters is: + *

+ * + *
+ * <module name="EmptyLineSeparator"/>
+ * 
+ * + *

+ * Example of declarations with blank line separator + * that is expected by the Check by default: + *

+ * + *
+ * package com.puppycrawl.tools.checkstyle.whitespace;
+ *
+ * import java.io.Serializable;
+ *
+ * class Foo
+ * {
+ *     public static final int FOO_CONST = 1;
+ *
+ *     public void foo() {}
+ * }
+ * 
+ *

An example how to check blank line after + * {@link TokenTypes#VARIABLE_DEF VARIABLE_DEF} and + * {@link TokenTypes#METHOD_DEF METHOD_DEF}: + *

+ * + *
+ * <module name="EmptyLineSeparator">
+ *    <property name="tokens" value="VARIABLE_DEF, METHOD_DEF"/>
+ * </module>
+ * 
+ * + * @author maxvetrenko + * + */ +public class EmptyLineSeparatorCheck extends Check +{ + + @Override + public int[] getDefaultTokens() + { + return new int[] { + TokenTypes.PACKAGE_DEF, + TokenTypes.IMPORT, + TokenTypes.CLASS_DEF, + TokenTypes.INTERFACE_DEF, + TokenTypes.ENUM_DEF, + TokenTypes.STATIC_INIT, + TokenTypes.INSTANCE_INIT, + TokenTypes.METHOD_DEF, + TokenTypes.CTOR_DEF, + TokenTypes.VARIABLE_DEF, + }; + } + + @Override + public void visitToken(DetailAST aAST) + { + final DetailAST nextToken = aAST.getNextSibling(); + + if (nextToken != null && nextToken.getType() != TokenTypes.RCURLY) { + final int astType = aAST.getType(); + switch (astType) { + case TokenTypes.VARIABLE_DEF: + if (isTypeField(aAST) && !hasBlankLineAfter(aAST)) { + log(nextToken.getLineNo(), + "empty.line.separator", nextToken.getText()); + } + break; + case TokenTypes.IMPORT: + if (astType != nextToken.getType() + && !hasBlankLineAfter(aAST)) + { + log(nextToken.getLineNo(), + "empty.line.separator", nextToken.getText()); + } + break; + default: + if (!hasBlankLineAfter(aAST)) { + log(nextToken.getLineNo(), + "empty.line.separator", nextToken.getText()); + } + } + } + } + + /** + * Checks if token have blank line after. + * @param aToken token. + * @return if token have blank line after. + */ + private boolean hasBlankLineAfter(DetailAST aToken) + { + DetailAST lastToken = aToken.getLastChild().getLastChild(); + if (null == lastToken) { + lastToken = aToken.getLastChild(); + } + return aToken.getNextSibling().getLineNo() - lastToken.getLineNo() > 1; + } + + /** + * If variable definition is a type field. + * @param aVariableDef variable definition. + * @return true variable definition is a type field. + */ + private boolean isTypeField(DetailAST aVariableDef) + { + final int parentType = aVariableDef.getParent().getParent().getType(); + return parentType == TokenTypes.CLASS_DEF; + } +} diff --git a/src/main/resources/com/puppycrawl/tools/checkstyle/checks/whitespace/messages.properties b/src/main/resources/com/puppycrawl/tools/checkstyle/checks/whitespace/messages.properties index 40dbc49da..f6776e7df 100644 --- a/src/main/resources/com/puppycrawl/tools/checkstyle/checks/whitespace/messages.properties +++ b/src/main/resources/com/puppycrawl/tools/checkstyle/checks/whitespace/messages.properties @@ -1,3 +1,5 @@ +empty.line.separator=''{0}'' should be separated from previous statement. + containsTab=Line contains a tab character. file.containsTab=File contains tab characters (this is the first instance). diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/checks/whitespace/EmptyLineSeparatorCheckTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/checks/whitespace/EmptyLineSeparatorCheckTest.java new file mode 100644 index 000000000..ba5bc05cd --- /dev/null +++ b/src/test/java/com/puppycrawl/tools/checkstyle/checks/whitespace/EmptyLineSeparatorCheckTest.java @@ -0,0 +1,48 @@ +//////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code for adherence to a set of rules. +// Copyright (C) 2001-2014 Oliver Burn +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//////////////////////////////////////////////////////////////////////////////// +package com.puppycrawl.tools.checkstyle.checks.whitespace; + +import com.puppycrawl.tools.checkstyle.BaseCheckTestSupport; +import com.puppycrawl.tools.checkstyle.DefaultConfiguration; +import org.junit.Before; +import org.junit.Test; + +public class EmptyLineSeparatorCheckTest + extends BaseCheckTestSupport +{ + private DefaultConfiguration mCheckConfig; + + @Before + public void setUp() + { + mCheckConfig = createCheckConfig(EmptyLineSeparatorCheck.class); + } + + @Test + public void testDefault() throws Exception + { + final String[] expected = { + "2: 'import' should be separated from previous statement.", + "16: 'CLASS_DEF' should be separated from previous statement.", + "19: 'VARIABLE_DEF' should be separated from previous statement.", + "58: 'INTERFACE_DEF' should be separated from previous statement.", + }; + verify(mCheckConfig, getPath("whitespace/InputEmptyLineSeparatorCheck.java"), expected); + } +} diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/whitespace/InputEmptyLineSeparatorCheck.java b/src/test/resources/com/puppycrawl/tools/checkstyle/whitespace/InputEmptyLineSeparatorCheck.java new file mode 100644 index 000000000..1f5792619 --- /dev/null +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/whitespace/InputEmptyLineSeparatorCheck.java @@ -0,0 +1,80 @@ +package com.puppycrawl.tools.checkstyle.whitespace; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.Collections; +import com.google.common.base.CharMatcher; +import com.google.common.io.CharSource; + +import javax.swing.AbstractAction; + +import org.apache.commons.beanutils.locale.converters.ByteLocaleConverter; +import org.apache.commons.io.FilenameUtils; +class InputEmptyLineSeparatorCheck +{ + public static final double FOO_PI = 3.1415; + private boolean flag = true; + //separator blank line + static { + //empty static initializer + } + //separator blank line + { + //empty instance initializer + } + //separator blank line + /** + * + * + */ + private InputEmptyLineSeparatorCheck() + { + //empty + } + //separator blank line + public int compareTo(InputGenericWhitespaceCheck aObject) + { + int number = 0; + return 0; + } + /** + * + * @param task + * @param result + * @return + */ + public static Callable callable(Runnable task, T result) + { + return null; + } + //separator blank line + public int getBeastNumber() + { + return 666; + } + interface IntEnum { + } + //separator blank line + class InnerClass { + + public static final double FOO_PI_INNER = 3.1415; + //separator blank line + private boolean flagInner = true; + //separator blank line + static { + //empty static initializer + } + //separator blank line + { + //empty instance initializer + } + //separator blank line + private InnerClass() + { + //empty + } + } +} diff --git a/src/xdocs/availablechecks.xml b/src/xdocs/availablechecks.xml index 6f3020272..595120142 100644 --- a/src/xdocs/availablechecks.xml +++ b/src/xdocs/availablechecks.xml @@ -134,6 +134,10 @@ space is required at an empty for iterator, or such spaces are forbidden. + + EmptyLineSeparator + Checks for blank line separators. + EmptyStatement diff --git a/src/xdocs/config_whitespace.xml b/src/xdocs/config_whitespace.xml index 97027cf7e..5c9f8f11e 100644 --- a/src/xdocs/config_whitespace.xml +++ b/src/xdocs/config_whitespace.xml @@ -1274,7 +1274,111 @@ import com.puppycrawl.tools.checkstyle.api.Check;

- com.puppycrawl.tools.checkstyle.checks + com.puppycrawl.tools.checkstyle.checks.whitespace +

+
+ + +

+ TreeWalker +

+
+ +
+ +

+ Checks for blank line separators after package, all import declarations, + fields, constructors, methods, nested classes, + static initializers and instance initializers. +

+
+ + + + + + + + + + + + + + + +
namedescriptiontypedefault value
tokensassignments to checksubset of tokens PACKAGE_DEF, + IMPORT, + CLASS_DEF, + ENUM_DEF + INTERFACE_DEF, + CTOR_DEF, + METHOD_DEF, + STATIC_INIT, + INSTANCE_INIT, + VARIABLE_DEF + All subset of tokens
+
+ + +

+ Example of declarations without blank line separator: +

+ +package com.puppycrawl.tools.checkstyle.whitespace; +import java.io.Serializable; +class Foo +{ + public static final int FOO_CONST = 1; + public void foo() {} //should be separated from previous statement. +} + +

+ An example of how to configure the check with default parameters is: +

+ +<module name="EmptyLineSeparator"/> + +

+ Example of declarations with blank line separator that is expected by the Check by default: +

+ +package com.puppycrawl.tools.checkstyle.whitespace; + +import java.io.Serializable; + +class Foo +{ + public static final int FOO_CONST = 1; + + public void foo() {} //should be separated from previous statement. +} + +

+ An example how to check blank line after VARIABLE_DEF and METHOD_DEF: +

+ +<module name="EmptyLineSeparator"> + <property name="tokens" value="VARIABLE_DEF, METHOD_DEF"/> +</module> + +
+ + +

+ com.puppycrawl.tools.checkstyle.checks.whitespace