IDEA外掛實現根據欄位註釋生成getter/setter方法Javadoc註釋

gjfLeo發表於2020-10-22

效果

註釋前程式碼示例:

public class ContactDto {
    /** id */
    private Long id;
    /** 聯絡人姓名 */
    private String contactName;
    
    public ContactDto() {}
    public ContactDto(Long id, String contactName) {
        this.id = id;
        this.contactName = contactName;
    }

    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public String getContactName() { return contactName; }
    public void setContactName(String contactName) { this.contactName = contactName; }
}

自動生成後:

package com.ssp.middle.demo.dto;

public class ContactDto {
    /** id */
    private Long id;
    /** 聯絡人姓名 */
    private String contactName;

    /**
     * 例項化一個新的ContactDto。
     */
    public ContactDto() {}

    /**
     * 例項化一個新的ContactDto。
     *
     * @param id          id
     * @param contactName 聯絡人姓名
     */
    public ContactDto(Long id, String contactName) {
        this.id = id;
        this.contactName = contactName;
    }

    /**
     * 獲取id。
     *
     * @return id
     */
    public Long getId() { return id; }

    /**
     * 設定id。
     *
     * @param id id
     */
    public void setId(Long id) { this.id = id; }

    /**
     * 獲取聯絡人姓名。
     *
     * @return 聯絡人姓名
     */
    public String getContactName() { return contactName; }

    /**
     * 設定聯絡人姓名。
     *
     * @param contactName 聯絡人姓名
     */
    public void setContactName(String contactName) { this.contactName = contactName; }
}

方法

步驟

  1. 下載安裝IDEA的JavaDoc外掛。
  2. 開啟選項:File - Settings - Tools - JavaDoc
  3. General選項卡:
    1. 我不想讓自動生成的註釋覆蓋手動新增的註釋,因此把Mode改成Update old javadoc。
    2. 我的目的是給欄位和方法加註釋,因此勾選Level中的Method(方法)和Field(欄位),取消勾選Type(類/介面/列舉)。
    3. 我想給所有元素(包括私有)加註釋,所以勾選Visibility中的全部4個。
    4. Other裡面我是全勾選的,不過應該沒有影響。
  4. Templates選項卡設定模板,見下文。

模板

Class Level

這裡可以設定類/介面/列舉的註釋模板,我這裡沒有使用(而且之前也取消勾選了)。

Constructor Level

這裡設定的是類和列舉的建構函式註釋模板。預設的模板我不用,因此我刪掉了,寫了一個對所有建構函式生效的模板:

匹配正規表示式:.+

/**\n
 * <#if element.parent.isEnum()>定義<#else>例項化</#if>一個新的${element.name}。\n
<#if element.parameterList.parameters?has_content>         *\n
</#if><#list element.parameterList.parameters as parameter>         * @param ${parameter.name} <#if element.getParent().findFieldByName(parameter.name,true)?? 
	  & element.getParent().findFieldByName(parameter.name,true).getDocComment()??
       >${element.getParent().findFieldByName(parameter.name,true).getDocComment().getDescriptionElements()[1].getText()?trim}<#else>${parameter.name}</#if>\n
</#list><#if element.throwsList.referenceElements?has_content>         *\n
</#if><#list element.throwsList.referenceElements as exception>         * @throws ${exception.referenceName} the ${exceptionNames[exception.referenceName]}\n
</#list> */

Method Level

這裡設定方法的註釋模板。自帶的四個模板分別是:getter,setter,main方法和所有方法。我這裡不用後兩個,因此直接刪了;getter和setter方法做了修改。

Getter方法

我只想給不帶引數的getXxx方法加註釋,因此修改了正規表示式最後的\(.*\).+,改為了\(\s*\).+。即:

匹配正規表示式:^.*(public|protected|private)*\s*.*(\w(\s*<.+>)*)+\s+get\w+\s*\(\s*\).+

模板:

/**\n
 * 獲取<#if element.getParent().findFieldByName(fieldName,true)?? 
	  & element.getParent().findFieldByName(fieldName,true).getDocComment()??
       >${element.getParent().findFieldByName(fieldName,true).getDocComment().getDescriptionElements()[1].getText()?trim}<#else>${fieldName}</#if>。\n
<#if element.typeParameters?has_content>         * \n
</#if><#list element.typeParameters as typeParameter>         * @param <${typeParameter.name}> \n
</#list><#if element.parameterList.parameters?has_content>         *\n
</#if><#list element.parameterList.parameters as parameter>         * @param ${parameter.name} <#if element.getParent().findFieldByName(parameter.name,true)?? 
	  & element.getParent().findFieldByName(parameter.name,true).getDocComment()??
       >${element.getParent().findFieldByName(parameter.name,true).getDocComment().getDescriptionElements()[1].getText()?trim}<#else>${parameter.name}</#if>\n
</#list><#if isNotVoid>         *\n
         * @return <#if element.getParent().findFieldByName(fieldName,true)?? 
	  & element.getParent().findFieldByName(fieldName,true).getDocComment()??
       >${element.getParent().findFieldByName(fieldName,true).getDocComment().getDescriptionElements()[1].getText()?trim}<#else>${fieldName}</#if>\n
</#if><#if element.throwsList.referenceElements?has_content>         *\n
</#if><#list element.throwsList.referenceElements as exception>         * @throws ${exception.referenceName}\n
</#list> */

這個模板和Setter保持了一致(除了“獲取”和“設定”兩個字)。

Setter方法

與Getter類似,我修改了一下正規表示式,限定了引數個數為一個:

匹配正規表示式:^.*(public|protected|private)*\s*.*(void|\w(\s*<.+>)*)+\s+set\w+\s*\(\S+\s+\S+\).+

模板和Getter一樣,除了“獲取”二字改成“設定”。

toString方法

另外我還單獨新增領toString方法的模板。

匹配正規表示式:^.*public\s+String\s+toString\s*\(\s*\).*

/** \n
 * 轉為字串。\n
 * \n
 * @return 字串\n
 */

Field Level

預設的欄位註釋模板是把欄位名的每個單詞拆開。我直接把所有欄位註釋模板改成了欄位名:

/** ${element.getName()} */

原理

簡單來說,就是${element}就是IDEA的外掛開發SDK中的PsiElement物件,可以從這裡開始順著文件樹,通過欄位名找到欄位的JavaDoc註釋。

相關文章