首页 > 解决方案 > PMD 可用于派生 IntelliSense 信息吗?

问题描述

(这是一个利基技术问题,但最终结果可能会引起更广泛的兴趣,所以我在这里问,但如果不值得交换 SO,我很乐意将讨论通过电子邮件发送。)

背景:我目前正在使用 PMD 对学生提交的作业进行样式检查。这是 PMD 和 CheckStyle 的组合,并以自定义格式输出,所以我已经以编程方式而不是从命令行使用 PMD。样式检查器运行后,我将输出显示在我们用于课程管理和作业评分的 web 应用程序中。

我想增强我的 webapp 以允许跳转到定义类型的交互,就像 IDE 一样。为此,我需要比ctags产生的更精确的输出。由于 PMD 已经进行 Java 解析和类型解析,因此可以想象 PMD 可用于识别文件中的所有名称并找出它们的绑定位置。

到目前为止的方法: 我已经想出了一种方法来运行解析器、NameResolution外观、Symbol外观、DataFlow外观、TypeResolution外观和Multifile外观,就像在SourceCodeProcessor逻辑中一样。(我不知道我是否需要所有这些,但我认为运行它们不会有什么坏处......)我试图定义我自己的 AST 访问者,其核心逻辑是

问题/疑问:

  1. 尽管装配了 auxClasspath 以包含正确的 jar,但名称解析有时无法解析例如assertEqualstoorg.junit.Assert.assertEquals或其他静态导入。我已经将执行跟踪到ClassTypeResolver,它似乎正在寻找org.junit.Assert类,但是当我的访问者开始运行时,相关ASTName节点有一个 null NameDeclaration 和一个 null Type。
  2. 我不明白如何确保可靠地检测到来自其他文件的符号。我认为这是一个设置正确的类路径和确保文件都是编译的东西,但我不能完全解释我有时看到的失败。
  3. 为什么ASTNames 有时由点状访问路径组成,例如someObject.someMethod被视为单个ASTName?我怎样才能独立获得这两个部分的名称解析?
  4. 在尝试获取可靠的名称和类型信息之前,我还需要运行其他访问者吗?
  5. (功能请求)这可能是值得 PMD 作为内置功能做的事情吗?

谢谢!

标签: pmd

解决方案


肯定有点超出范围,所以最好去 PMD 开发邮件列表,或者直接给我们的维护人员发电子邮件是最好的。

尽管如此,由于到目前为止似乎没有人对这个问题有任何疑问,我会尽可能完整地回答。

  1. 类型解析代码尝试标记每个节点的类型。对于方法调用foo(bar, baz),这意味着寻找任何foo返回类型(不是定义的类型foo)。因为Assert.assertEquals返回类型void非常理想,这就是您应该看到的。有一些警告。PMD 类型解析的这个特定领域仍然不完整(我们可以很好地解决更简单的场景,但在类型推断发挥作用的困难场景中挣扎)。非常感谢有关此区域的任何错误报告/ PR。
  2. 符号表中的符号还是类型?记住符号表仍然是单文件。类型不是,但这就是为什么我们也需要项目自己的编译类auxclasspath
  3. Legacy… 我们计划以一种或另一种方式改变它(参见#497),但这样做是对 AST 构建方式的重大改变,这反过来意味着使用所有规则ASTName(在 PMD 中和由用户构建)很可能会完全停止工作……请提供任何反馈或想法。
  4. 不,你实际上跑的比你需要的多。仅使用符号表和类型解析就可以了(按此顺序!)
  5. 也许……您可以在 PMD 上起草一个 RFC 问题以更好地讨论可能的用例……不过,除了我们是否以某种方式公开符号表之外,您尝试做的其他大多数事情都是我们关心的事情。

推荐阅读