pmd - PMD 可用于派生 IntelliSense 信息吗?
问题描述
(这是一个利基技术问题,但最终结果可能会引起更广泛的兴趣,所以我在这里问,但如果不值得交换 SO,我很乐意将讨论通过电子邮件发送。)
背景:我目前正在使用 PMD 对学生提交的作业进行样式检查。这是 PMD 和 CheckStyle 的组合,并以自定义格式输出,所以我已经以编程方式而不是从命令行使用 PMD。样式检查器运行后,我将输出显示在我们用于课程管理和作业评分的 web 应用程序中。
我想增强我的 webapp 以允许跳转到定义类型的交互,就像 IDE 一样。为此,我需要比ctags产生的更精确的输出。由于 PMD 已经进行 Java 解析和类型解析,因此可以想象 PMD 可用于识别文件中的所有名称并找出它们的绑定位置。
到目前为止的方法: 我已经想出了一种方法来运行解析器、NameResolution
外观、Symbol
外观、DataFlow
外观、TypeResolution
外观和Multifile
外观,就像在SourceCodeProcessor
逻辑中一样。(我不知道我是否需要所有这些,但我认为运行它们不会有什么坏处......)我试图定义我自己的 AST 访问者,其核心逻辑是
- 访问
ASTName
节点 - 得到他们
NameDeclaration
的 - 记录声明的源位置和节点的源位置,作为 def->use 对
问题/疑问:
- 尽管装配了 auxClasspath 以包含正确的 jar,但名称解析有时无法解析例如
assertEquals
toorg.junit.Assert.assertEquals
或其他静态导入。我已经将执行跟踪到ClassTypeResolver
,它似乎正在寻找org.junit.Assert
类,但是当我的访问者开始运行时,相关ASTName
节点有一个 null NameDeclaration 和一个 null Type。 - 我不明白如何确保可靠地检测到来自其他文件的符号。我认为这是一个设置正确的类路径和确保文件都是编译的东西,但我不能完全解释我有时看到的失败。
- 为什么
ASTName
s 有时由点状访问路径组成,例如someObject.someMethod
被视为单个ASTName
?我怎样才能独立获得这两个部分的名称解析? - 在尝试获取可靠的名称和类型信息之前,我还需要运行其他访问者吗?
- (功能请求)这可能是值得 PMD 作为内置功能做的事情吗?
谢谢!
解决方案
肯定有点超出范围,所以最好去 PMD 开发邮件列表,或者直接给我们的维护人员发电子邮件是最好的。
尽管如此,由于到目前为止似乎没有人对这个问题有任何疑问,我会尽可能完整地回答。
- 类型解析代码尝试标记每个节点的类型。对于方法调用
foo(bar, baz)
,这意味着寻找任何foo
返回类型(不是定义的类型foo
)。因为Assert.assertEquals
返回类型void
非常理想,这就是您应该看到的。有一些警告。PMD 类型解析的这个特定领域仍然不完整(我们可以很好地解决更简单的场景,但在类型推断发挥作用的困难场景中挣扎)。非常感谢有关此区域的任何错误报告/ PR。 - 符号表中的符号还是类型?记住符号表仍然是单文件。类型不是,但这就是为什么我们也需要项目自己的编译类
auxclasspath
。 - Legacy… 我们计划以一种或另一种方式改变它(参见#497),但这样做是对 AST 构建方式的重大改变,这反过来意味着使用所有规则
ASTName
(在 PMD 中和由用户构建)很可能会完全停止工作……请提供任何反馈或想法。 - 不,你实际上跑的比你需要的多。仅使用符号表和类型解析就可以了(按此顺序!)
- 也许……您可以在 PMD 上起草一个 RFC 问题以更好地讨论可能的用例……不过,除了我们是否以某种方式公开符号表之外,您尝试做的其他大多数事情都是我们关心的事情。
推荐阅读
- sql - 在不同行的两个日期之间生成 SQL
- javascript - 纱线安装 --force 错误。我在安装完成之前收到此错误
- c# - C# 处理和加密大文件时内存不足
- python - 在 python 中添加 try / except 块后未创建文件
- unit-testing - JUnit 5 - 运行测试类以保持系统状态
- c# - Refit 6, net 5 error 无法确定帧大小或收到损坏的帧
- amazon-web-services - polly.us-east-2.amazonaws.com/v1/speech 在 ubuntu 18 上返回 200 但在 ubuntu 16 服务器上禁止 403
- node.js - 使用 Node.js 捕获/监听本地 HTTPS 请求
- google-sheets - 如何将时间戳列附加到存档数据脚本
- bluetooth-lowenergy - BLE 广告是否需要提供非空本地名称?