【问题标题】:Java checkstyle: Check whether or not return type is X if method name contains YJava checkstyle:如果方法名称包含Y,则检查返回类型是否为X
【发布时间】:2020-08-19 13:03:52
【问题描述】:

我正在尝试编写一个 checkstyle 规则,如果名称通过某个正则表达式,则验证方法的返回类型。

例如:如果方法名称包含Foo,我想确保返回类型不是Bar

通过:

public Fizz testFoo() {}

public Optional<Fizz> testFoo2() {}

失败:

public Bar testFoo() {}

public Optional<Bar> fooTest() {}

【问题讨论】:

    标签: java checkstyle


    【解决方案1】:

    您可以构建自己的支票并使用它

    例如,这是可以解决您的问题的自定义检查

    XML 配置

    <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

    【讨论】:

      【解决方案2】:

      我不明白这些问题,但可能是这个代码合作

      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!");  
                      }
                  }
              }
      

      【讨论】:

      • 谢谢。我更多地考虑了这个插件的 xml 配置文件中的自定义 checkstyle 规则:checkstyle.sourceforge.io
      猜你喜欢
      • 1970-01-01
      • 2013-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-02
      • 2010-11-29
      • 2014-04-12
      相关资源
      最近更新 更多