Let's say we have the following piece of code:
public class Demo {
@ABC(name = "abc")
private String field1;
@ABC
private String field2;
}
@interface ABC {
String name() default "";
}
How can I write a query that selects all the fields annotated with @ABC
that does not have the name
property?
There's getValue(string)
method in Annotation
object, but getValue("name")
returns empty string for the annotation on field2
because it's the default value. But I am wondering how can I check if that property is even there, mentioned by the author.
Unfortunately CodeQL does not provide any predicates for this out of the box (see also this related issue). However, you can exploit the fact that default value
Expr
does not seem to have a location in source (i.e. itsgetLocation()
has a.class
file location as result).You could then have a utility predicate, such as the following, to detect whether an annotation has a default value for an element:
But keep in mind that this behavior is not explicitly defined, and could change in the future, or bugs with the CodeQL extractor could cause false positives here. Additionally this does not work for annotations which occur in dependencies or the JDK, since the annotation itself is then not present in source either.