PMD:如何仅忽略 lambda 表达式中的短变量名

PMD: How to ignore short variable names in lambda expressions only

我正在寻找一种解决方案,它允许我使用 PMD 检查短变量名,同时从该规则中排除 lambda。

主要是因为 IntelliJ 会自动用单个字符命名常见的 lamba 变量,尤其是。 java.lang.String 总是缩写为

aListFullOfStrings.forEach(s -> s.replaceAll(" ", ""));

我更喜欢这个缩写,但我不想对我所有的 lambda 表达式添加抑制。我找不到任何方法来调整我的 PMD 规则以优雅地解决这个问题。

非常感谢您的建议 - 我对他们的所有配置都不是很有经验。

默认情况下,PMD 会标记名称少于 3 个字符的变量,尽管它已经豁免了一些合法的情况,例如 for 循环变量。您需要调整 PMD,以便它也免除 lambda 表达式中的变量。

这是通过修改位于 jar 文件 {pmd 安装目录}[=68 中名为 naming.xml 的 PMD 的许多规则集文件之一来完成的=].8.1.jar(如果您使用的是最新版本的 PMD)。一种方法如下:

  • 解压jar文件pmd-java-5.8.1.jar到某个临时文件夹

  • 编辑提取的文件naming.xml并找到文本rule name="ShortVariable" 然后插入文本 [not(ancestor::LambdaExpression)] 如下面粗体所示。

[not(ancestor::ForInit)]
[not(ancestor::LambdaExpression)] [not(../../VariableDeclarator and ../../../LocalVariableDeclaration and ../../../../ForStatement)]
[not((ancestor::FormalParameter) and (ancestor::TryStatement))]

  • 您还可以选择对规则集文件进行进一步调整。

  • 使用修改后的 naming.xml 重新创建 jar 文件。此命令执行此操作:

    jar cf pmd-java-5.8.1.jar 网络规则集 META-INF

我不知道你的PMD插件是什么风格和版本,但他们应该都使用pmd-java-5.8.1.jar 或它的一些早期版本。我只是使用 PMD 本身而不是插件做了一个简单的概念验证,并使用此方法从命令行验证了 class:

void test() {
    Consumer<String> consumer = (String s) -> System.out.println(s);
    consumer.accept("Hello world!!!");
}

PMD 5.8.1 版报告了该代码中 lambda 变量的违规情况:

然而,在如上所述修改 naming.xml 之后,违规行为消失了。

您可以利用基于 xpath 的 PMD 抑制功能。

在您的规则集 XML 上,只需为此特定规则配置 属性 即可:

<rule ref="rulesets/java/naming.xml/ShortMethodName">
  <properties>
    <property name="violationSuppressXPath" value=".[ancestor::LambdaExpression]"/>
  </properties>
</rule>

尽管如此,作为 PMD 维护者,我认为这是更改 PMD 本身规则的合法案例,因此我添加了 github.com/pmd/pmd/issues/720 来跟踪这一点。

较新的 PMD 版本现在在命名规则集中使用 ShortVariable 规则。我在我的 ruleset.xml 中使用它来消除 lambda 的错误。它仍然捕获短的非 lambda 变量。

<rule ref="rulesets/java/naming.xml/ShortVariable">
    <properties>
        <property
                name="violationSuppressXPath" value=".[ancestor::LambdaExpression]"/>
    </properties>
</rule>