It can be done with CheckStyle, but you'll have to code a custom check.
Using a custom check allows you to completely ignore comments. The line number that a token is on can be determined by calling getLineNo()
on the DetailAST. Here's what the AST looks like, with line number information (red circles):
The custom check's code will likely be quite short. You basically register for LITERAL_ELSE
tokens and see if LITERAL_IF
is their only child. Also remember to handle SLIST
s. In those cases, LITERAL_IF
and RCURLY
should be the only children. Both cases are illustrated in the above picture.
Alternative using a RegExp check
For the record, I originally thought one could also configure a regex match using else[ \t{]*[\r\n]+[ \t{]*if\b
for the format
property (based on this post).
Here's the mentioned regex as a railroad diagram:
This turned out not to be feasible, because it produces false negatives when there are comments between between else
and if
. Worse, it also produces false positives when the nested if
is followed by unrelated code (like else { if() {...} <block of code>}
. Thanks @Anatoliy for pointing this out! Since comments and matching braces which are mixed with comments cannot be reliably grasped by regexes, these problems obsolete the RegExp approach.