PMD 可用于派生 IntelliSense 信息吗?

Posted

技术标签:

【中文标题】PMD 可用于派生 IntelliSense 信息吗?【英文标题】:Can PMD be used to derive IntelliSense information? 【发布时间】:2018-10-12 19:46:46 【问题描述】:

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

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

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

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

访问ASTName节点 获取他们的NameDeclarations 记录声明的源位置和节点的源位置,作为def->use对

问题/疑问:

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

谢谢!

【问题讨论】:

【参考方案1】:

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

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

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

【讨论】:

以上是关于PMD 可用于派生 IntelliSense 信息吗?的主要内容,如果未能解决你的问题,请参考以下文章

Intellisense和浏览信息将不能用于C++项目,请确保已经安装Microsoft SQLserver compact 3.5 是啥意思

IntelliSense:“没有可用的附加信息”,[请参见“C++项目 IntelliSense 疑难解答”,获得进一步的帮助]

IntelliSense:“没有可用的附加信息”,[请参见“C++项目 IntelliSense 疑难解答”,获得进一步的帮助]

隐式构造函数可用于从 Base 派生的所有类型(当前类型除外)?

GDB 可以用于在 Fortran 90 中打印派生类型的可分配数组的值吗? [复制]

用于数据绑定的 IntelliSense 不起作用