允许不带 else 的简单 if 语句在代码风格中没有大括号

问题描述 投票:0回答:4

我使用 checkstyle 检查我的 Java 代码是否遵循我们项目的准则。

但是,我们有一个指导方针,我无法弄清楚如何使用此工具进行检查。我们希望允许简单的 if (理解其中没有 else 且没有其他条件结构的 if )没有大括号,就像在这个例子中一样:

// 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();

这个约定可以讨论,但这是我们选择的。它允许在非常简单的情况下减少 if 语法,但确保我们对于更复杂的结构有良好的缩进和块分隔。

如有任何帮助,我们将不胜感激。

如果没有可用的内容,我还准备编写一些代码来执行此检查,但真的不知道从哪里开始。在最后的手段中,一些有关这方面的提示也将不胜感激。

java if-statement checkstyle
4个回答
5
投票

最后,我确实实现了 checkstyle 的自定义检查。如果其他人对此感兴趣,这是源代码:

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 conditional 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;
                }
            }
        }
    }
}

1
投票

只想补充一点,现在 checkstyle 支持 'allowSingleLineIf' 属性,该属性涵盖了某些情况。

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

0
投票

虽然我同意这是一个坏主意的评论,但您可能无法更改指南。所以你可能想尝试这个:

  1. 在 checkstyle 模块中 Blocks -> 需要大括号,禁用 if 关键字
  2. 创建模块的新实例 Regexp -> RegexpSingleLineJava 并尝试找到与您的无效案例匹配但与有效案例不匹配的正则表达式

(模块名称来自 Eclipse Checkstyle Plugin 5.3.0)


0
投票

CheckStyle 6.14 NeedBracesCheck rool 支持 allowSingleLineStatement 选项

allowSingleLineStatement 允许不带大括号的单行语句,例如:

if(obj.isValid())返回true;

while (obj.isValid()) 返回 true;

执行此操作。notify(); while (o != null);

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

文档

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.