Type annotation always unknown

I’m developing a rule for inclusion in SonarJava and need to access the type of annotations. More specifically, I’m looking to find the fully qualified name of Foo in types like List<@Foo Object> (type annotations introduced by Java 8).

For some reason, however, the symbol for Foo always returns true for isUnknown(), and I consequently cannot access the fully qualified name. Is this a bug or somehow my mistake? I tried switching the navigation code from declarations to metadata as indicated in an answer to a remotely related question, but get the same result.

Here is the shortened version of my reproducer (see this commit in my SonarJava fork):

Check implementation

@Rule(key = "X1234")
public class BugDemoCheck extends IssuableSubscriptionVisitor {
  @Override
  public List<Tree.Kind> nodesToVisit() {
    return ImmutableList.of(Tree.Kind.ANNOTATION);
  }

  @Override
  public void visitNode(Tree tree) {
    AnnotationTree annotationTree = (AnnotationTree) tree;
    Symbol.TypeSymbol annotationSymbol = annotationTree.symbolType().symbol();
    if (annotationSymbol.isUnknown()) {
      reportIssue(annotationTree, "Unknown annotation symbol");
    }
  }
}

Test class

@interface MyAnnotation {
}

class MyClass {
  java.util.List<@MyAnnotation Object> field; // Issue reported here
}

Notes

  • As written, this reports an issue in the marked line.
  • If I change the element type in the test class from Object to Object[], no issue is reported. Is this maybe somehow related to type erasure?

Just, a guess

Your code sample does not compile on my side. Adding @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) to annotation declaration fixing the compilation. May be this is the problem.

P.S. About your last comment, do you mean that with Object[] you have a symbol and can access fully qualified name?

No, I simply left that out as it didn’t change the behavior of the check.

Exactly. For this line, no issue is reported:

java.util.List<@MyAnnotation Object[]> objectArrays;

To make things more obvious, I pushed another commit with a compilable test class and an additional field of object arrays.

Hey @bannmann,

Thanks a lot for the feedback. Nice finding!

I had a look and it seems to be a bug in the semantic engine. Apparently, we are not (at all) resolving the type of the annotation in this very specific case, while we are correctly resolving it when using an array or another parameterized type. We probably forgot to handle this case when adding the support of Java 8 type annotations.

I created the following ticket to handle it: SONARJAVA-3045

Cheers,
Michael

1 Like