1. 程式人生 > 實用技巧 >PMD - 用 Java 開發程式碼規則

PMD - 用 Java 開發程式碼規則

在 PMD 的使用過程中,可以用 Java 或 XPath 來開發程式碼規則。

本文講述如何使用 Java 來開發。

AST 對應的 Java 類庫

PMD 使用抽象語法樹(AST)來分析程式碼。它本身已經建立了一系列的 Java 類庫來操作不同的語法元素。

針對 Apex 語言的 6.22.0 API 的官方文件

在使用 Java 開發規則時,我們主要就是利用這些類來分析程式碼,從而找出違反規則的情況。

比如:

  • ASTAnnotation:對應的是註解,比如 @IsTest
  • ASTBreakStatement:對應的是 break 語句
  • ASTWhileLoopStatement:對應的是 while 迴圈
  • ASTLiteralExpression:對應的是字串賦值語句

實現步驟

  1. 建立新的 Java 類
  2. 重寫 visit() 函式,在函式中分析程式碼,找到違反規則的部分
  3. 將規則註冊到規則集檔案中

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>

這樣,這條規則就可以使用了。