Java checkstyle: 检查方法名中是否包含Y,如果是,则检查返回类型是否为X。

huangapple go评论75阅读模式
英文:

Java checkstyle: Check whether or not return type is X if method name contains Y

问题

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

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

通过示例:

public Fizz testFoo() {}

public Optional<Fizz> testFoo2() {}

不通过示例:

public Bar testFoo() {}

public Optional<Bar> fooTest() {}
英文:

I'm trying to write a checkstyle rule that verifies the return type of a method if the name passes a certain regex.

e.g: If the method name contains Foo, I want to make sure that the return type isn't Bar.

Passes:

public Fizz testFoo() {}

public Optional&lt;Fizz&gt; testFoo2() {}

Fails:

public Bar testFoo() {}

public Optional&lt;Bar&gt; fooTest() {}

答案1

得分: 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);
                }
            }
        }
    }
}

此检查的使用示例:

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

此链接将帮助您构建自己的自定义检查:https://checkstyle.sourceforge.io/writingchecks.html

英文:

You can build your own check and use it

for example this is custom check that can solve your problem

The XML Config

&lt;module name=&quot;Checker&quot;&gt;
&lt;module name=&quot;TreeWalker&quot;&gt;
&lt;module name=&quot;ReturnTypeNameCheck&quot;&gt;
&lt;property name=&quot;methodNameFormat&quot; value=&quot;.*Foo&quot;/&gt;
&lt;property name=&quot;returnNameFormat&quot; value=&quot;String&quot;/&gt;
&lt;/module&gt;
&lt;/module&gt;
&lt;/module&gt;

The Custom check code

public class ReturnTypeNameCheck extends AbstractCheck {
public static final String MSG_KEY = &quot;return.type.name.check&quot;;
private String methodNameFormat = &quot;&quot;;
private String returnNameFormat = &quot;&quot;;
@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 &amp;&amp; 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);
}
}
}
}

Examples of vol for this Check

class Test {
public void testFoo() {} //OK
public String testFoo() {} //violation
public ClassOne&lt;String&gt; testFoo() {}  //violation
public ClassOne&lt;ClassTwo&lt;String&gt;&gt; testFoo() {}  //violation
public ClassOne&lt;ClassTwo&lt;ClassThree&lt;String&gt;&gt;&gt; testFoo() {}  //violation
}

and this link will help you to build your own custom Check
https://checkstyle.sourceforge.io/writingchecks.html

答案2

得分: 0

我不太了解这些问题,但也许这段代码可能是这样的:

Method[] methods = this.getClass().getMethods();
for (Method method : methods) {
    if(method.getName().contains("Foo")){
        if(!method.getReturnType().getClass().getName().contains("Foo")){
            throw new Exception("返回类型错误!");
        }
    }
}
英文:

I dont understand mụch about the questions but may be this code co

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

huangapple
  • 本文由 发表于 2020年5月5日 07:45:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/61603495.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定