SonarQube自定义规则-获取方法参数所有者类

时间:2018-09-21 11:20:52

标签: java tree sonarqube

目前,我正在修复自定义声纳规则。

private void reportMethodParametersClassContainingInternalAnnotation(MethodTree methodTree) {
    if (!methodTree.parameters().isEmpty()) {
        for (int i = 0; i < methodTree.parameters().size(); i++) {
            if (!isParameterWrapperType(methodTree, i) && parameterClassContainsInternalAnnotation(methodTree, i)) {
                reportIssue(methodTree.parameters().get(i),
                        methodTree.parameters().get(i).type().symbolType().fullyQualifiedName()
                                + " class must be annotated @CanInvoke or must be standart java class");
            }
        }
    }
}

private static final ArrayList<String> WRAPPER_TYPES = new ArrayList<String>(Arrays.asList("Boolean", "Character",
        "Byte", "Short", "Integer", "Long", "Float", "Double", "void", "String", "int"));

private static boolean isParameterWrapperType(MethodTree tree, int i) {
    return WRAPPER_TYPES.contains(tree.parameters().get(i).type().symbolType().name());
}

private boolean parameterClassContainsInternalAnnotation(MethodTree tree, int i) {
    return tree.parameters().get(i).type().symbolType().symbol().metadata()
            .isAnnotatedWith(Constants.INTERNAL_ANNOTATION_PATH);
}

这是方法,在方法中搜索参数。一一得到之后,方法应检查参数的类是否具有@Internal注释(来自我公司的自定义注释)。如果有,方法将报告问题。 到目前为止,它工作正常。但是当它找到某个类的数组的参数时,最后一个方法试图检查的不是那个类,而是数组(显然没有@Internal)。

更清楚地说,这是示例:

当方法参数是这样的时候:

public void hello(SimpleClass simpleClass) {

}

最后一个方法返回:

true

还有:

tree.parameters().get(i).type().symbolType().symbol().name();

返回此:

SimpleClass

但是当方法参数是这样的时候:

public void hello(SimpleClass... simpleClass) {

}

最后一个方法返回:

false

还有:

tree.parameters().get(i).type().symbolType().symbol().name();

返回此:

Array

应该使用哪种方法来使此参数成为真实所有者并能够检查其是否带有特定注释?

1 个答案:

答案 0 :(得分:1)

一旦有了参数的类型,就应该检查它是否是数组,然后可以将其强制转换为具有Type.ArrayType方法的elementType(),该方法返回数组元素的类型。

这里是一个小例子,怎么做

MethodTree methodTree = (MethodTree) tree;
  for (VariableTree parameter : methodTree.parameters()) {
    Type parameterType = parameter.type().symbolType();
    if (parameterType.isArray()) {
      Type.ArrayType arrayType = (Type.ArrayType) parameterType;
      if (arrayType.elementType().symbol().metadata().isAnnotatedWith("MyAnnotation")) {
        // do something
      }
    }
  }