Java: Add convenience predicates for AnnotationType

This commit is contained in:
Marcono1234
2021-07-10 23:14:31 +02:00
committed by Chris Smowton
parent f69b6eef7a
commit 02c8fe9346
2 changed files with 38 additions and 8 deletions

View File

@@ -227,10 +227,43 @@ class AnnotationType extends Interface {
/** Holds if this annotation type is annotated with the meta-annotation `@Inherited`. */
predicate isInherited() {
exists(Annotation ann |
ann.getAnnotatedElement() = this and
ann.getType().hasQualifiedName("java.lang.annotation", "Inherited")
)
getADeclaredAnnotation().getType().hasQualifiedName("java.lang.annotation", "Inherited")
}
/** Holds if this annotation type is annotated with the meta-annotation `@Documented`. */
predicate isDocumented() {
getADeclaredAnnotation().getType().hasQualifiedName("java.lang.annotation", "Documented")
}
/**
* Gets the retention policy of this annotation type, that is, the name of one of the
* enum constants of `java.lang.annotation.RetentionPolicy`. If no explicit retention
* policy is specified the result is `CLASS`.
*/
string getRetentionPolicy() {
if getADeclaredAnnotation() instanceof RetentionAnnotation
then result = getADeclaredAnnotation().(RetentionAnnotation).getRetentionPolicy()
else
// If not explicitly specified retention is CLASS
result = "CLASS"
}
/**
* Holds if the element type is a possible target for this annotation type.
* The `elementType` is the name of one of the `java.lang.annotation.ElementType`
* enum constants. If no explicit target is specified for this annotation type
* it is considered to be applicable to all elements.
*/
// Note: Cannot use a predicate with string as result because annotation type without
// explicit @Target can be applied to all targets, requiring to hardcode element types here
bindingset[elementType]
predicate isATargetType(string elementType) {
if getADeclaredAnnotation() instanceof TargetAnnotation
then elementType = getADeclaredAnnotation().(TargetAnnotation).getATargetElementType()
else
// No Target annotation means "applicable to all contexts" since JDK 14, see https://bugs.openjdk.java.net/browse/JDK-8231435
// The compiler does not completely implement that, but pretend it did
any()
}
}

View File

@@ -19,8 +19,5 @@ where
m.getNumberOfParameters() = 1 and
c.getArgument(0).getType() = p and
p.getATypeArgument() = t and
not exists(RetentionAnnotation a |
t.getAnAnnotation() = a and
a.getAValue().(VarAccess).getVariable().hasName("RUNTIME")
)
t.getRetentionPolicy() != "RUNTIME"
select c, "Call to isAnnotationPresent where no annotation has the RUNTIME retention policy."