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
节点
获取他们的NameDeclaration
s
记录声明的源位置和节点的源位置,作为def->use对
问题/疑问:
-
尽管安装了 auxClasspath 以包含正确的 jar,但名称解析有时无法解析,例如
assertEquals
到 org.junit.Assert.assertEquals
,或其他静态导入。我已经追踪到ClassTypeResolver
的执行,它似乎正在找到org.junit.Assert
类,但是当我的访问者开始运行时,相关的ASTName
节点有一个空的NameDeclaration 和一个空的类型。
我不明白如何确保可靠地检测到来自其他文件的符号。我认为这是一种设置正确的类路径和确保文件全部编译的事情,但我无法完全解释我有时看到的失败。
为什么ASTName
s 有时包含点状访问路径,例如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 派生的所有类型(当前类型除外)?