0

假设我们有以下代码:

public class Demo {
    @ABC(name = "abc")
    private String field1;

    @ABC
    private String field2;
}

@interface ABC {
    String name() default "";
}

如何编写一个查询来选择所有带有注释@ABC但不具有该name属性的字段?

对象中有getValue(string)方法Annotation,但由于它是默认值,所以getValue("name")为注释返回空字符串。field2但是我想知道作者提到的如何检查该属性是否存在。

4

1 回答 1

0

不幸的是,CodeQL 没有为此提供任何开箱即用的谓词(另请参阅此相关问题)。Expr但是,您可以利用默认值似乎在源中没有位置的事实(即,它getLocation()有一个.class文件位置作为结果)。

然后,您可以使用实用谓词(如下所示)来检测注释是否具有元素的默认值:

predicate hasDefaultValue(Annotation annotation, string elementName) {
  // If value file location is not the same as annotation file location, then most likely it
  // is the default value (unless there is a bug with the CodeQL extractor)
  annotation.getValue(elementName).getLocation().getFile() != annotation.getLocation().getFile()
}

但请记住,此行为没有明确定义,并且将来可能会发生变化,或者 CodeQL 提取器的错误可能会导致误报。此外,这不适用于依赖项或 JDK 中出现的注解,因为注解本身也不存在于源代码中。

于 2022-03-05T17:17:19.233 回答