Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rule to enforce blank lines as wrap of class declaration #3379

Closed
mcandre opened this issue Jul 29, 2016 · 13 comments
Closed

Rule to enforce blank lines as wrap of class declaration #3379

mcandre opened this issue Jul 29, 2016 · 13 comments

Comments

@mcandre
Copy link

mcandre commented Jul 29, 2016

Oracle, IBM, Google, and Mozilla Java code often inserts a blank line between the opening curly brace of a class declaration and the class contents, as well as a blank line between the contents and the closing class curly brace. For example:

https://github.com/oracle/atg-build-tools/blob/master/atg-maven-plugin/src/main/java/com/oracle/atg/ateam/RunAssemblerMojo.java

Classes with no contents require no blank lines:

public class SomeClass {}

Could Checkstyle please feature a rule that enforces n (0, 1, 2, ...) blank lines in this context?

There appears to be a rule for enforcing a blank line at the beginning of class declarations, but I can't find one to enforce a blank line at the end as well.

@eric-milles
Copy link

eric-milles commented Aug 12, 2016

I can understand the blank line at the start of the class def to give some space before the first field or method. But why at the end? A closing brace followed by another with proper indentation seems fine.

    }
}

I can tell the class is closed as the last brace in the file, also no indent clues me in.

If you wanted to enforce this under the current Checkstyle, you could leverage the fact that the brace is at column 0 and write a RegexMultiline check. This would not help you for inner classes/interfaces/enums though.

@plastiv
Copy link

plastiv commented Oct 3, 2016

Interesting enough, we have exact the opposite code style convention of removing an empty line between closing braces, but I can't find a way to enforce it with the checkstyle.

@mcandre
Copy link
Author

mcandre commented Oct 3, 2016

Interesting enough, we have exact the opposite code style convention of removing an empty line between closing braces, but I can't find a way to enforce it with the checkstyle.

Awesome! I'd love to see support for enforcing both styles in Checkstyle configuration.

@eric-milles
Copy link

To enforce no blank lines at the beginning and end of any block, we use multi-line regular expression checks:

    <module name="RegexpMultiline">
        <property name="message" value="Blank line at start of block should be removed" />
        <property name="format" value="(?&lt;=\{\s{0,99}$)^$" />
        <property name="fileExtensions" value="groovy,java" />
    </module>
    <module name="RegexpMultiline">
        <property name="message" value="Blank line at end of block should be removed" />
        <property name="format" value="(?&lt;!\{\s{0,99}$)^$(?=^\s{0,99}\})" />
        <property name="fileExtensions" value="groovy,java" />
    </module>

"^$" signifies the blank line.

@romani romani changed the title Rule to enforce popular Java class declaration whitespace style Rule to enforce blank lines as wrap of class declaration Jan 28, 2017
@romani
Copy link
Member

romani commented Jan 28, 2017

@mcandre ,

we have one more request for the same feature https://groups.google.com/forum/#!topic/checkstyle/rzNJDM_uvyg , and looks like I lost tracking of this issue.

Could Checkstyle please feature a rule that enforces n (0, 1, 2, ...) blank lines in this context?

please explain why you need multiple lines (2 empty lines or more) ?

@romani
Copy link
Member

romani commented Mar 5, 2017

This issue is hard to read and understand what is requested.

I created new issue #3923 with clear request for new functionality.

request for "rule that enforces n (0, 1, 2, ...) blank lines in this context" is skipped as author did not explain a reason of it.

Implementation of new option as described in new issue will not brake compatibility with existing functionality.

If somebody care about NoEmptyLineSeparator - please create new issue and define usecases. @plastiv , please do. There was similar request at #3089 (comment) . @robertpainsi .

@romani romani closed this as completed Mar 5, 2017
@ati90ati
Copy link

ati90ati commented Nov 13, 2018

UPDATE: for better answer check this: #3379 (comment)

Quick solution with multiline regex (the code should be well formatted):

<module name="RegexpMultiline">
    <property name="format" value="^([^\n ]+ )*(class|interface|enum) [^{]*\{\n[^\n}]"/>
    <property name="message" value="Leave empty row after class/interface/enum definition!"/>
    <property name="severity" value="error"/>
    <property name="fileExtensions" value="groovy,java"/>
</module>

<module name="RegexpMultiline">
    <property name="format" value="[^\n{]\n\}\n"/>
    <property name="message" value="Leave empty row before end of class/interface/enum!"/>
    <property name="severity" value="error"/>
    <property name="fileExtensions" value="groovy,java"/>
</module>

@GuyLewin
Copy link

@ati90ati for Windows support, I added \r:

<module name="RegexpMultiline">
    <property name="format" value="^([^[\r]?\n ]+ )*(class|interface|enum) [^{]*\{[\r]?\n[^\r\n}]"/>
    <property name="message" value="Leave empty row after class/interface/enum definition!"/>
    <property name="severity" value="error"/>
    <property name="fileExtensions" value="groovy,java"/>
</module>

<module name="RegexpMultiline">
    <property name="format" value="[^\r\n{][\r]?\n\}[\r]?\n"/>
    <property name="message" value="Leave empty row before end of class/interface/enum!"/>
    <property name="severity" value="error"/>
    <property name="fileExtensions" value="groovy,java"/>
</module>

@ati90ati
Copy link

ati90ati commented Apr 22, 2020

@GuyLewin I've checked your suggestion.

For me, the first stopped working. It's not supposed to have this in regex: [^[\r]?\n ]
Bracket in bracket not supposed to be used.

My current approach is this (I adapted your Windows support, this is my best guess however I have not tested it on Windows):

    <module name="RegexpMultiline">
        <!--
        To fix all occurrences (with IntelliJ IDEA 2018 on Linux tested)
        Add newline at class start (file mask *.java)
        Find: (^([^\r\n ]+ )*(class|interface|@interface|enum) [^{]*\{[\r]?\n)([^\r\n}])
        Replace: $1\n$4
        -->
        <property name="id" value="RegexpMultilineEmptyRowAfterClassDef"/>
        <property name="format" value="^([^\r\n ]+ )*(class|interface|@interface|enum) [^{]*\{[\r]?\n[^\r\n}]"/>
        <property name="message" value="Leave empty row after class/interface/@interface/enum definition!"/>
        <property name="severity" value="error"/>
        <property name="fileExtensions" value="groovy,java"/>
    </module>

    <module name="RegexpMultiline">
        <!--
        To fix all occurrences (with IntelliJ IDEA 2018 on Linux tested)
        Add newline at class end (file mask *.java)
        Find: ([^\r\n{][\r]?\n)(\}[\r]?\n)
        Replace: $1\n$2
        -->
        <property name="id" value="RegexpMultilineEmptyRowBeforeClassEnd"/>
        <property name="format" value="[^\r\n{][\r]?\n\}[\r]?\n"/>
        <property name="message" value="Leave empty row before end of class/interface/@interface/enum!"/>
        <property name="severity" value="error"/>
        <property name="fileExtensions" value="groovy,java"/>
    </module>

UPDATE 2:
To handle inner classes too, check out this suggestion: #3379 (comment)

@pavelicii
Copy link

@ati90ati, thank you for the solution!

If I also want to check inner/nested classes for RegexpMultilineEmptyRowAfterClassDef, is it OK to change format to:

^([\t ]*[^\r\n ]+ )*(class|interface|@interface|enum) [^{]*\{[\r]?\n[^\r\n}]?

(added [\t ]* in the beginning to allow spaces/tabs before nested class definition)

@romani
Copy link
Member

romani commented Dec 21, 2021

it would be awesome if somebody find a time to formalize #5313 and even implement it.

@ati90ati
Copy link

@pavelicii I updated my comment with the latest regex I have. I think your suggestion is accurate if you want to check inner classes too.

@Orachigami
Copy link

Extended version of @pavelicii pattern:
^([ \t]{0,}@\w+[ \t]*(\(.*\))?)?[ \t]{0,}([a-z]+ )*(class|@?interface|enum)[^{]+\{[ \t]{0,}(?=\r?\n[ \t]{0,}(?!\})[^\s]|[^\r\n]*[^\s])

I added annotation checks and empty class declaration ignoring

Demo can be checked here:
https://regex101.com/r/ELsq2R/3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants