【发布时间】:2017-06-13 19:51:41
【问题描述】:
我尝试编写自定义声纳规则 (Java),并努力寻找正确的方法来获取调用的 Java 方法的注释。
此规则应检测对标记为@VisibleForTesting 的方法和字段的非法访问。从生产代码访问这些元素是非法的,但从同一类访问是合法的。
我的第一种方法是实现BaseTreeVisitor.visitMethodInvocation(MethodInvocationTree) 并使用所属符号的元数据:
- 获取注释:
methodInvocationSymbol.metadata().annotations() - 分析每个
AnnotationInstance(注解类)及其所有者(注解包)的符号名称
只要其他类调用该方法,它就可以很好地工作。当调用在同一个类中时 - 注释名称和包被设置为!unknownSymbol!。
我还尝试了另一种方法:分析AnnotationTree的IdentifierTree(在BaseTreeVisitor.visitMethodInvocation(MethodInvocationTree))内部,但是我找不到如何获取注解的包名的方法。
我使用 sonar-java-plugin 3.7.1 和 sonar-plugin-api 5.1。
代码提交在这个mvn / Eclipse project。
UnexpectedAccessCheckTest 包含 2 个用例。 “InvokedFromOtherClass”运行良好。 InvokedFromSameClass 通过了测试,但这只是偶然发生的——注释没有被正确检测到。
它产生这个输出:
[main] DEBUG d.t.s.p.vft.checks.IsAnAnnotation - Checking Annotation.
Expected [com.google.common.annotations.VisibleForTesting]
got [.!unknownSymbol!]
正确的运行用例会产生这样的结果:
[main] DEBUG d.t.s.p.vft.checks.IsAnAnnotation - Checking Annotation.
Expected [com.google.common.annotations.VisibleForTesting]
got [com.google.common.annotations.VisibleForTesting]
你有什么提示吗?
【问题讨论】:
-
能否请您准确说明您正在使用的 sonar-java 插件版本?如果我正确地回答了您的问题,那么您的问题是何时要检查在与其声明相同的源文件中调用的方法?您描述的第一种方法应该可以工作,如果没有,那么很可能该方法没有解决。你能分享一个不起作用的示例案例吗?
-
@benzonico 感谢您的快速回答!我使用 3.7.1 的 sonar-java-plugin 和 5.1 的 sonar-plugin-api
-
如果对您有帮助,请点赞并接受答案。
-
您共享了代码,但这还不清楚,您想要检测的模式究竟是什么,哪些没有按预期工作?