Java checkstyle: Проверить, является ли возвращаемый тип X, если имя метода содержит Y - PullRequest
1 голос
/ 05 мая 2020

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

например: если имя метода содержит Foo, я хочу убедиться что тип возвращаемого значения не Bar.

Проходит:

public Fizz testFoo() {}

public Optional<Fizz> testFoo2() {}

Ошибка:

public Bar testFoo() {}

public Optional<Bar> fooTest() {}

Ответы [ 2 ]

0 голосов
/ 29 мая 2020

Вы можете создать свой собственный чек и использовать его

например, это настраиваемая проверка, которая может решить вашу проблему

XML Config

<module name="Checker">
   <module name="TreeWalker">
       <module name="ReturnTypeNameCheck">
          <property name="methodNameFormat" value=".*Foo"/>
          <property name="returnNameFormat" value="String"/>
       </module>
    </module>
</module>

Пользовательский код проверки

public class ReturnTypeNameCheck extends AbstractCheck {

    public static final String MSG_KEY = "return.type.name.check";

    private String methodNameFormat = "";
    private String returnNameFormat = "";

    @Override
    public int[] getDefaultTokens() {
        return getRequiredTokens();
    }

    @Override
    public int[] getAcceptableTokens() {
        return getRequiredTokens();
    }

    @Override
    public int[] getRequiredTokens() {
        return new int[] {TokenTypes.METHOD_DEF};
    }

    public final void setMethodNameFormat(String format) {
        methodNameFormat = format;
    }

    public final void setReturnNameFormat(String format) {
        returnNameFormat = format;
    }

    @Override
    public void visitToken(DetailAST ast) {
        DetailAST methodName = ast.findFirstToken(TokenTypes.IDENT);
        DetailAST methodType = ast.findFirstToken(TokenTypes.TYPE);

        String methodNameStr = methodName.getText();
        String returnTypeName = methodType.getFirstChild().getText();

        if(methodNameStr.matches(methodNameFormat)) {
            if(methodType.branchContains(TokenTypes.TYPE_ARGUMENTS)){

                DetailAST typeArgs = methodType.getLastChild();
                while (typeArgs != null && typeArgs.getChildCount(TokenTypes.TYPE_ARGUMENT) != 0) {
                    typeArgs = typeArgs.findFirstToken(TokenTypes.TYPE_ARGUMENT);
                    String genericTypeName = typeArgs.findFirstToken(TokenTypes.IDENT).getText();

                    if(genericTypeName.contains(returnNameFormat)){
                        log(ast, MSG_KEY);
                        return;
                    }

                    typeArgs = typeArgs.getLastChild();
               }
            } else{
                if(returnTypeName.contains(returnNameFormat)){
                    log(ast, MSG_KEY);
                }
            }
        }
    }

Примеры vol для этой проверки

class Test {
   public void testFoo() {} //OK
   public String testFoo() {} //violation
   public ClassOne<String> testFoo() {}  //violation
   public ClassOne<ClassTwo<String>> testFoo() {}  //violation
   public ClassOne<ClassTwo<ClassThree<String>>> testFoo() {}  //violation
}

, и эта ссылка поможет вам создать свой собственный проверочный https://checkstyle.sourceforge.io/writingchecks.html

0 голосов
/ 05 мая 2020

Я ничего не понимаю в вопросах, но может быть это код co

Method[] methods = this.getClass().getMethods();
        for (Method method : methods) {
            if(method.getName().contains("Foo")){
                if(!method.getReturnType().getClass().getName().contains("Foo")){
                    throw new Exception("Wrong return type!");  
                }
            }
        }
...