PMD源代码分析器允许将规则编写为XPath expressions。
我正在清理Apex代码库,经常发现以下错误:!someCollection.isEmpty() && someCollection != null
。
正确的方法是先检查null:someCollection != null && !someCollection.isEmpty()
。
使用我的trusted editor,我可以使用RegEx查找以下项目:&& [a-zA-Z0-9]* != null
。奇迹般有效。现在,我尝试为其创建自定义PMD规则,但是我的XPath regex在PMD设计器中不返回任何值:
<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')]
,但是即使返回任何结果也没有。
我想念什么?
应该触发规则的示例Apex:
global class caseShareBatch {
global void execute(List<Case> caseShareList){
if(!caseShareList.isEmpty() && caseShareList != null) {
insert caseShareList;
}
}
}
答案 0 :(得分:1)
您确定PMD支持XPath 2.0吗?快速浏览文档,这并不明显。经常谈论没有版本号的XPath的人通常指的是XPath 1.0,它当然没有matches()
功能。
答案 1 :(得分:1)
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
匹配,因此您必须进一步优化查询。不幸的是,我没有发现任何可以区分&&
和||
的东西,但是您可能会遇到好运。
答案 2 :(得分:0)
结果证明,PMD 6.10无法实现我需要做的事情。 latest release 6.11.0并没有像我期望的那样公开@Image
属性,但是在布尔运算符中添加了足够的新属性以形成值得@ michael-kay的XPath表达式,而无需向其中添加Regex混合:
//BooleanExpression[@Op="&&"][
child::*[2][
self::BooleanExpression[@Op="!="][
child::*[1][self::VariableExpression] and
child::*[2][self::LiteralExpression[@LiteralType="NULL"]]
]
]
]
YMMV