如何使用XPath在PMD中检查Apex源字符串?

时间:2019-01-09 06:04:29

标签: xpath apex pmd

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&lt;Case&gt; caseShareList){
     if(!caseShareList.isEmpty() &amp;&amp; caseShareList != null) {
            insert caseShareList;
     }
}
}

3 个答案:

答案 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规则时提供很多帮助。

PMD Rule Designer

对于此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