Разрешить простой оператор if без других, чтобы в коде стиля не было фигурных скобок - PullRequest
12 голосов
/ 26 мая 2011

Я использую checkstyle , чтобы проверить, соответствует ли мой код Java руководящим принципам нашего проекта.

Однако у нас есть одна рекомендация, которую я не могу понять, как проверить с помощью этого инструмента. Мы хотим разрешить простому 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 для очень тривиальных случаев, но гарантирует, что у нас есть хорошие отступы и разделение блоков для более сложных структур.

Любая помощь с этим была бы очень признательна.

Я также готов сделать некоторый код для выполнения этой проверки, если ничего не доступно, но на самом деле не знаю, с чего начать. В последнем сообщении, некоторые советы об этом также будут оценены.

Ответы [ 4 ]

5 голосов
/ 27 мая 2011

В конце я реализовал пользовательскую проверку для стиля проверки.Вот исходный код, если кому-то еще это интересно:

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;
                }
            }
        }
    }
}
1 голос
/ 21 января 2015

Просто хочу добавить, что теперь checkstyle поддерживает свойство 'allowSingleLineIf', которое охватывает некоторые случаи.

    <module name="NeedBraces">
        <property name="allowSingleLineIf" value="true"/>
    </module>
0 голосов
/ 12 января 2016

CheckStyle 6.14. NeedBracesCheck rool support allowSingleLineStatement option

allowSingleLineStatement, который допускает однострочные операторы без скобок, например:

if (obj.isValid ()) верните истину;

, а (obj.isValid ()) верните истину;

сделайте this.notify ();while (o! = null);

для (int i = 0;;) this.notify ();

документация

0 голосов
/ 27 мая 2011

Хотя я согласен с комментариями, что это плохая идея, вы не сможете изменить руководящие принципы. Так что вы можете попробовать это:

  1. В модуле checkstyle Блоки -> Нужны скобки , отключите ключевое слово , если
  2. Создайте новый экземпляр модуля Regexp -> RegexpSingleLineJava и попытайтесь найти регулярное выражение, которое соответствует вашим недействительным случаям, но не действительным

(Имена модулей взяты из Eclipse Checkstyle Plugin 5.3.0)

...