如何使用 XPath 检查 PMD 中的 Apex 源字符串?
How to check for an Apex source string in PMD using XPath?
PMD 源代码分析器允许将规则编写为 XPath expressions。
我正在清理 Apex 代码库,我经常发现以下错误:!someCollection.isEmpty() && someCollection != null
.
正确的方法是先检查是否为 null:someCollection != null && !someCollection.isEmpty()
.
使用我的 trusted editor 我可以使用 RegEx 查找这些项目:&& [a-zA-Z0-9]* != null
。奇迹般有效。现在我尝试为其创建自定义 PMD 规则,但我的 XPath 正则表达式在 PMD Designer 中没有 return 任何值:
<rule message="Apex code must check != null before .isEmpty()" name="NullValueCheckBeforeEmptyCheck" class="net.sourceforge.pmd.lang.rule.XPathRule">
<description>Apex code must check != null before .isEmpty()</description>
<priority>1</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//*[matches(@Image,'&& [a-zA-Z0-9]* != null')]
]]>
</value>
</property>
</properties>
</rule>
我尝试进行初始检查 //*[matches(@Image,'if')]
但即便如此 return 也没有结果。
我错过了什么?
应触发规则的示例 Apex:
global class caseShareBatch {
<pre><code>global void execute(List<Case> caseShareList){
if(!caseShareList.isEmpty() && caseShareList != null) {
insert caseShareList;
}
}
}
您确定 PMD 支持 XPath 2.0 吗?快速浏览一下文档,这并不明显。很多时候谈论没有版本号的 XPath 的人指的是 XPath 1.0,它当然没有 matches()
功能。
PMD 使用 Apex 解析器将源代码转换为抽象语法树 (AST)。您的 XPath 表达式应用于 AST,而不是源代码。例如。 if 语句的 AST 看起来像这样:
IfElseBlockStatement {
IfBlockStatement {
StandardCondition {
BooleanExpression {
PrefixExpression {
MethodCallExpression {
ReferenceExpression
}
}
BooleanExpression {
VariableExpression
LiteralExpression
}
}
}
BlockStatement {
DmlInsertStatement {
VariableExpression
}
}
}
}
PMD 有一个图形 rule designer 在编写 XPath 规则时很有帮助。
对于这个 AST,XPath //BooleanExpression/BooleanExpression[position() > 0 and VariableExpression and LiteralExpression]
匹配 && caseShareList != null
。但它也会匹配 || i == 42
因此您必须进一步优化查询。不幸的是,我没有看到任何可以让我区分 &&
和 ||
的东西,但你可能运气更好。
事实证明,PMD 6.10 无法实现我需要做的事情。 latest release 6.11.0 没有像我希望的那样暴露 @Image
属性 ,而是在布尔运算符中添加了足够的新属性以形成值得 @michael-kay 的 XPath 表达式,而不需要将正则表达式添加到组合中:
//BooleanExpression[@Op="&&"][
child::*[2][
self::BooleanExpression[@Op="!="][
child::*[1][self::VariableExpression] and
child::*[2][self::LiteralExpression[@LiteralType="NULL"]]
]
]
]
YMMV
PMD 源代码分析器允许将规则编写为 XPath expressions。
我正在清理 Apex 代码库,我经常发现以下错误:!someCollection.isEmpty() && someCollection != null
.
正确的方法是先检查是否为 null:someCollection != null && !someCollection.isEmpty()
.
使用我的 trusted editor 我可以使用 RegEx 查找这些项目:&& [a-zA-Z0-9]* != null
。奇迹般有效。现在我尝试为其创建自定义 PMD 规则,但我的 XPath 正则表达式在 PMD Designer 中没有 return 任何值:
<rule message="Apex code must check != null before .isEmpty()" name="NullValueCheckBeforeEmptyCheck" class="net.sourceforge.pmd.lang.rule.XPathRule">
<description>Apex code must check != null before .isEmpty()</description>
<priority>1</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//*[matches(@Image,'&& [a-zA-Z0-9]* != null')]
]]>
</value>
</property>
</properties>
</rule>
我尝试进行初始检查 //*[matches(@Image,'if')]
但即便如此 return 也没有结果。
我错过了什么?
应触发规则的示例 Apex:
global class caseShareBatch {
<pre><code>global void execute(List<Case> caseShareList){
if(!caseShareList.isEmpty() && caseShareList != null) {
insert caseShareList;
}
}
}
您确定 PMD 支持 XPath 2.0 吗?快速浏览一下文档,这并不明显。很多时候谈论没有版本号的 XPath 的人指的是 XPath 1.0,它当然没有 matches()
功能。
PMD 使用 Apex 解析器将源代码转换为抽象语法树 (AST)。您的 XPath 表达式应用于 AST,而不是源代码。例如。 if 语句的 AST 看起来像这样:
IfElseBlockStatement {
IfBlockStatement {
StandardCondition {
BooleanExpression {
PrefixExpression {
MethodCallExpression {
ReferenceExpression
}
}
BooleanExpression {
VariableExpression
LiteralExpression
}
}
}
BlockStatement {
DmlInsertStatement {
VariableExpression
}
}
}
}
PMD 有一个图形 rule designer 在编写 XPath 规则时很有帮助。
对于这个 AST,XPath //BooleanExpression/BooleanExpression[position() > 0 and VariableExpression and LiteralExpression]
匹配 && caseShareList != null
。但它也会匹配 || i == 42
因此您必须进一步优化查询。不幸的是,我没有看到任何可以让我区分 &&
和 ||
的东西,但你可能运气更好。
事实证明,PMD 6.10 无法实现我需要做的事情。 latest release 6.11.0 没有像我希望的那样暴露 @Image
属性 ,而是在布尔运算符中添加了足够的新属性以形成值得 @michael-kay 的 XPath 表达式,而不需要将正则表达式添加到组合中:
//BooleanExpression[@Op="&&"][
child::*[2][
self::BooleanExpression[@Op="!="][
child::*[1][self::VariableExpression] and
child::*[2][self::LiteralExpression[@LiteralType="NULL"]]
]
]
]
YMMV