ling ma
ling ma

Reputation: 11

ClassCastException: org.sonar.java.model.declaration.VariableTreeImpl

I am trying to make my own SonarQube rule, the objective of the rule is to check that there should be a white space between a variable and an equality sign. For example:

int num=3; // Noncompliant 
int num = 3; // Compliant 

To do that I am trying to get the VariableTreeImpl to use the method equalToken(). so I should change the type VariableTree to VariableTreeImpl

@Override
public void visitClass(ClassTree tree) {
    if (tree.is(Tree.Kind.CLASS) || tree.is(Tree.Kind.ENUM)) {
        for (Tree member : tree.members()) {
            if (member.is(Tree.Kind.VARIABLE)) {   
                if (((VariableTree) member).initializer() != null && ((VariableTreeImpl)member).equalToken()!= null  ){
                    SyntaxToken variableFistToken = ((VariableTree) member).simpleName().firstToken();
                    SyntaxToken initializerToken = ((VariableTree) member).initializer().firstToken();
                    if (noSpacingBetweenEqualSign(variableFistToken,initializerToken,((VariableTreeImpl) member).equalToken())) {
                        context.reportIssue(this, member, "Before and after equals sign should have white space");
                    }
                }
            }
        }
    }
    super.visitClass(tree);
}

It seems to work well during jUnit tests but when I launch sonnar-scanner on my test project I get the following error:

Caused by: java.lang.ClassCastException: org.sonar.java.model.declaration.VariableTreeImpl cannot be cast to org.sonar.java.model.declaration.VariableTreeImpl
  at com.gisquest.custom.sonar.check.DeclareVariableCheck.visitClass(DeclareVariableCheck.java:39)
  at org.sonar.java.model.declaration.ClassTreeImpl.accept(ClassTreeImpl.java:198)
  at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:43)
  at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:37)
  at org.sonar.plugins.java.api.tree.BaseTreeVisitor.visitCompilationUnit(BaseTreeVisitor.java:55)
  at org.sonar.java.model.JavaTree$CompilationUnitTreeImpl.accept(JavaTree.java:184)
  at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:43)
  at com.gisquest.custom.sonar.check.DeclareVariableCheck.scanFile(DeclareVariableCheck.java:29)
  at org.sonar.java.model.VisitorsBridge.visitFile(VisitorsBridge.java:121)
  at org.sonar.java.ast.JavaAstScanner.simpleScan(JavaAstScanner.java:84)
  ... 38 more
ERROR: 

I have done some research and I came across this question, that looks to be my problem : SonarQube java.lang.ClassCastException: ParametrizedTypeJavaType cannot be cast to ParametrizedTypeJavaType

So I am totally confused. What is the good approach to deal with my problem?

I'm using SonarQube version 6.2.

Upvotes: 1

Views: 414

Answers (1)

Wohops
Wohops

Reputation: 3121

Unfortunately, because the equalToken() is not part of the VariableTree API interface yet, your rule won't have access to it at runtime. Implementation of these interfaces are not exposed, but available during test phases.

There is not much you can do at this point, as long as the API is not changed, except maybe change your approach and only subscribe to syntax tokens. Then check for = strings, and if the equal operator is part of VariableTree (using parent() method), and finally check for location of tokens spaces.

In the same time, I created the following ticket to enrich the API and provide access for the equal token: SONARJAVA-2432

EDIT: note that as you are writing custom rules for the SonarJava plugin, providing version of the SonarJava analyzer could help, and it has an independant lifecycle than SonarQube.

Upvotes: 2

Related Questions