PMD - 用 Java 開發程式碼規則
阿新 • • 發佈:2020-07-28
在 PMD 的使用過程中,可以用 Java 或 XPath 來開發程式碼規則。
本文講述如何使用 Java 來開發。
AST 對應的 Java 類庫
PMD 使用抽象語法樹(AST)來分析程式碼。它本身已經建立了一系列的 Java 類庫來操作不同的語法元素。
在使用 Java 開發規則時,我們主要就是利用這些類來分析程式碼,從而找出違反規則的情況。
比如:
- ASTAnnotation:對應的是註解,比如 @IsTest
- ASTBreakStatement:對應的是 break 語句
- ASTWhileLoopStatement:對應的是 while 迴圈
- ASTLiteralExpression:對應的是字串賦值語句
實現步驟
- 建立新的 Java 類
- 重寫 visit() 函式,在函式中分析程式碼,找到違反規則的部分
- 將規則註冊到規則集檔案中
在 GitHub 中可以參考現有規則的 Java 實現。
舉例
規則:程式碼中不能出現 System.debug() 函式。
建立新的 Java 類
建立一個新的類,名叫 SystemDebugShouldBeAvoidedRule,並且擴充套件 AbstractApexRule 類。
import java.util.List; import net.sourceforge.pmd.lang.apex.ast.*; import net.sourceforge.pmd.lang.apex.rule.*; public class SystemDebugShouldBeAvoidedRule extends AbstractApexRule { }
重寫 visit() 函式
在新的類中重寫 visit() 函式。
因為規則檢測的入口是函式,所以引數是 ASTMethod 型別。
AST 類庫中定義了很多方法,比如 findDescendantsOfType() 可以得到某個程式碼塊下面的所有特定型別的元素。
import java.util.List; import net.sourceforge.pmd.lang.apex.ast.*; import net.sourceforge.pmd.lang.apex.rule.*; public class SystemDebugShouldBeAvoidedRule extends AbstractApexRule { @Override public Object visit(ASTMethod node, Object data) { boolean hasSystemDebug = false; // 得到所有的呼叫函式的程式碼 List<ASTMethodCallExpression> methodCallList = node.findDescendantsOfType(ASTMethodCallExpression.class); for (ASTMethodCallExpression methodCall : methodCallList) { // 得到函式名 String assertMethodName = methodCall.getFullMethodName(); // 和 "system.debug" 比較 if ("system.debug".equalsIgnoreCase(assertMethodName)) { hasSystemDebug = true; break; } } if (hasSystemDebug) { // addViolationWithMessage() 函式會生成警告 addViolationWithMessage(data, node, "''{0}'' method should not have System.Debug function.", new Object[] { node.getImage() }); } // 返回 data,其中會包含警告資訊 return data; } }
將規則註冊到規則集檔案中
每個規則集都是以 XML 形式出現的。我們將新的規則註冊進去:
<rule name="SystemDebugShouldBeAvoided"
since="6.23.0"
language="apex"
message="System Debug should be avoided"
class="<Java類的路徑>.SystemDebugShouldBeAvoidedRule">
<description>
System Debug should be avoided
</description>
<priority>4</priority> <!-- 優先順序從 1 到 5,表示從最嚴重到最輕微的規則-->
<example>
<![CDATA[
public void doSomething() {
System.debug('test');
}
]]>
</example>
</rule>
這樣,這條規則就可以使用了。