可以检查导入是否错误?在编写自定义规则时

时间:2017-02-24 16:40:58

标签: java sonarqube

我想写一个java规则如果导入的类是APIClass注释并且导入的类有问题,则会产生问题。我正在关注this教程。

代码:

首先,我写了一条简单的规则:

@Rule( key = "ForbidClassVariables", name = "ForbidClassVariables")
public class ForbidClassVariables extends BaseTreeVisitor implements JavaFileScanner {

private JavaFileScannerContext context;

@Override
public void scanFile(JavaFileScannerContext context) {
    this.context = context;
    if (context.getSemanticModel() != null) {
        scan(context.getTree());
    }       
}

@Override
public void visitClass(ClassTree tree) {
    if (tree.modifiers().annotations().size() > 0 && hasAnnotation(tree.modifiers().annotations(), "APIClass")) {
        if (hasClassVariables(tree)) {
            this.context.reportIssue(this, tree.simpleName(), "Do not use class variables on API Classes.");
        }
    }
    super.visitClass(tree);
}

private boolean hasAnnotation(List<AnnotationTree> annotations, String annotationName) {
    for (AnnotationTree annotation : annotations) {
        if (annotation.annotationType().is(Tree.Kind.IDENTIFIER)
                && ((IdentifierTree) annotation.annotationType()).name().equals(annotationName)) {
            return true;
        }
    }
    return false;
}

private boolean hasClassVariables(ClassTree tree) {
    for (Tree member : tree.members()) {
        if (member.is(Tree.Kind.VARIABLE)) {
            VariableTree variableTree = (VariableTree) member;
            Symbol symbol = variableTree.symbol();
            if (!symbol.isStatic() || !symbol.isFinal()) {
                return true;
            }
        }
    }
    return false;
}
}

我创建了一个测试类文件ExampleA.java

package br.com.test;

@APIClass
public class ExampleA {
    private String name;
}

当我运行测试时,在第4行产生错误,这是预期的。

问题的关键点:我创建了另一条规则:

@Rule( key = "CheckIFClassIsOK", name = "CheckIFClassIsOK")
public class CheckIFImportedClassIsOK  extends BaseTreeVisitor implements JavaFileScanner{

private JavaFileScannerContext context;

@Override
public void scanFile(JavaFileScannerContext context) {
    this.context = context;
    if (context.getSemanticModel() != null) {
        scan(context.getTree());
    }       
}

@Override
public void visitImport(ImportTree tree) {
    IdentifierTree identifier = ((MemberSelectExpressionTree) tree.qualifiedIdentifier()).identifier();

    System.out.println(identifier); // Shows ExampleA

    // At this point I need re-scan ExampleA class and IF the scan generate any issue
    // Will generate another here Issue on ExampleB

    super.visitImport(tree);
}   
}

并使用此文件进行测试:

import br.com.test.ExampleA;

public class ExampleB {

    private ExampleA exampleA;

}

问题是,当我访问导入时,如果导入的类具有APIClass注释并且存在问题,则会在ExampleB.java上生成问题以避免使用此导入,因为存在问题。我在树类上搜索了很多,但我没有找到任何有用的东西。我想我需要强制重新扫描ExampleA.java,但是如何?有人有想法吗?

声纳版本:6.2 Java插件版本:4.5.0.8398

感谢您的关注

1 个答案:

答案 0 :(得分:0)

不幸的是,这是不可能的。 API中没有办法从另一个文件请求解析树。但是,您可以检索有关类ExampleB中成员的语义信息,但这不包括注释。