查找对象的 class

Find object's class

目前我的任务是迁移SonarQube 中的一些规则。旧的基于 PMD 和 Checkstyle 库。新的需要用集成的 Sonar 规则编写(就像大多数鱿鱼规则)。我目前正在处理的规则需要检查 class 中是否在循环中使用了名称中包含 "Dao" 的任何方法。

我对规则迁移和声纳库的使用不是很有经验,所以我尝试使用 squid 规则中的一些部分,但我无法找到我需要的东西。

@Override
public void visitNode(Tree tree) {
   MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree;
   IdentifierTree methodName = methodName(methodInvocationTree);

   if ( methodClassContainsDaoInName(tree?) && insideLoop(tree?)) {
      reportIssue(methodName, "DAO methods should not be called inside loop");
   }
}

我仍然停留在第一个方法 (methodClassContainsDaoInName()) 上。目前我正在尝试获取方法和对象并检查该对象的 class 名称中是否包含 "Dao" 。我使用这个命令:

tree.parent().firstToken().text();

此命令找到了我的对象,但只给出了它的名称。我尝试这样做:

tree.parent().firstToken().toClass();

但它给了我错误的 class(如果我没记错的话 returns 符号或标记 class)。

也许有人知道如何将该结果转换为正确的对象? 也许有人知道使这条规则生效的更好方法并可以分享一些例子?

作为免责声明,我不会为您编写规则。 API(语法或语义)中的所有内容都应该可用...一旦在规则编写和概念方面正确表达了您的要求。

重新制定要求:您正在尝试验证 class(对象...)拥有 被调用的方法是一个 DAO(a.k.a. owner), 如果是这样,提出一个问题(如果它在一个循环中,那是另一回事了)。

现在,从您已经拥有的 methodInvocationTree 本身,访问其关联的 symbol(API 中有一个 symbol() 方法),然后它是 owner 符号, 应该 是拥有的 class。从所有者符号中,您可以直接访问它的 name,并验证它是否包含 "Dao"。

放入代码:

boolean methodFromDao = methodInvocationTree
  .symbol()
  .owner()
  .name()
  .contains("Dao");

重要说明: 从语法 API 中,您使用了 SonarJava API 的另一个抽象级别,它使您可以访问符号。为了完成语义,SonarJava 需要在分析期间访问字节码。如果未提供字节码,语义引擎很可能无法解析方法。具体来说,就是所有的符号都是unknown,你将无法知道它们的主人。