开发者

Allow simple if statement without else to have no braces in codestyle

I use checkstyle to check if my java code respects the guidelines of our project.

However, we have one guideline that I cannot figure out how to check with this tool. We want to allow simple if (understand if with no else and no other conditional structure in it) to have no brace, like in this example :

// valid
if(condition) callFunction();

// invalid
if(condition) for(int i = 0; i < someValue; i++) callFunction(i);

// valid
if(condition) {
    for(int i = 0; i < someValue; i++) {
        callFunction(i);
    }
}

// invalid
if(condition) callFunction();
else callOtherFunction();

This convention can be discussed, but this is the one we 开发者_如何学JAVAchose. It allows a reduced if syntax for very trivial cases, but ensures we have good indentation and block delimitation for more complex structures.

Any help with that would be really appreciated.

I'm also ready to do some code to perform this check if nothing is available, but really don't know where to start. In last ressort, some tips about that will be appreciated too.


At the end, I did implement a custom check for checkstyle. Here is the source code if someone else is interested in it :

import com.puppycrawl.tools.checkstyle.api.Check;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;

public class IfBracesCheck extends Check {

    @Override
    public int[] getDefaultTokens() {
        return new int[] {
            TokenTypes.LITERAL_ELSE,
            TokenTypes.LITERAL_IF,
        };
    }

    @Override
    public void visitToken(DetailAST aAST) {
        final DetailAST slistAST = aAST.findFirstToken(TokenTypes.SLIST);

        if(aAST.getType() == TokenTypes.LITERAL_ELSE) {
            // If we have an else, it must have braces, except it is an "else if" (then the if must have braces).
            DetailAST ifToken = aAST.findFirstToken(TokenTypes.LITERAL_IF);

            if(ifToken == null) {
                // This is an simple else, it must have brace.
                if(slistAST == null) {
                    log(aAST.getLineNo(), "ifBracesElse", aAST.getText());
                }
            } else {
                // This is an "else if", the if must have braces.
                if(ifToken.findFirstToken(TokenTypes.SLIST) == null) {
                    log(aAST.getLineNo(), "ifBracesConditional", ifToken.getText(), aAST.getText() + " " + ifToken.getText());
                }
            }
        } else if(aAST.getType() == TokenTypes.LITERAL_IF) {
            // If the if uses braces, nothing as to be checked.
            if (slistAST != null) {
                return;
            }

            // We have an if, we need to check if it has no conditionnal structure as direct child.
            final int[] conditionals = {
                TokenTypes.LITERAL_DO,
                TokenTypes.LITERAL_ELSE,
                TokenTypes.LITERAL_FOR,
                TokenTypes.LITERAL_IF,
                TokenTypes.LITERAL_WHILE,
                TokenTypes.LITERAL_SWITCH,
            };

            for(int conditional : conditionals) {
                DetailAST conditionalAST = aAST.findFirstToken(conditional);

                if (conditionalAST != null) {
                    log(aAST.getLineNo(), "ifBracesConditional", aAST.getText(), conditionalAST.getText());

                    // Let's trigger this only once.
                    return;
                }
            }
        }
    }
}


Just want to add that now checkstyle supports 'allowSingleLineIf' property which covers some cases.

    <module name="NeedBraces">
        <property name="allowSingleLineIf" value="true"/>
    </module>


While I agree with the comments that this is a bad idea, you might not be able to change the guidelines. So you might want to try this:

  1. In the checkstyle module Blocks -> Need braces, disable the if keyword
  2. Create a new instance of the module Regexp -> RegexpSingleLineJava and try to find a regexp that matches your invalid cases but not your valid ones

(Module names are from Eclipse Checkstyle Plugin 5.3.0)


CheckStyle 6.14 NeedBracesCheck rool support allowSingleLineStatement option

allowSingleLineStatement which allows single-line statements without braces, e.g.:

if (obj.isValid()) return true;

while (obj.isValid()) return true;

do this.notify(); while (o != null);

for (int i = 0; ; ) this.notify();

documentation

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜