IntelliJ IDEAで自動コード生成

AvatarPosted by

この記事はGRIPHONE Advent Calendar 2021 17日目の記事です。

こんにちは。サーバーサイドエンジニアのtackです。

IntelliJには最初から様々な便利機能が入っています。その中に新しくソースコードのファイルを作る時に、自動的にコードのひな形を生成してくれる”File and Code Templates”という機能があるので、使い方を紹介します。

※この記事では、IntelliJを使っていますが、PHPStorm、Goland、PyCharmなどJetBrainsのIDEなら使えます。

FileTemplateとは

IntelliJのFileTemplateは、ファイルを新しく生成するときに使われます。Projectビューを右クリックしてNewを選ぶと、以下の画像の様に沢山のファイルが表示されます。これらのほとんどがFileTemplateで定義されています。

FileTemplateは既存の物を変更したり、新しく追加することもできます。

FileTemplateを見てみる

FileTemplateを変更するには“File”メニューから“Settings”を開き、“Editor”の中にある“File and Code Templates”を開きます。

設定画面の左側に出てくるリストがFileTemplateになります。この画面ではFileのテンプレート以外にもIncludes、Code、Otherというタブがあり、他のテンプレートも変更することができます。(今回はFileのみ紹介します)

リストの項目をクリックすることで、テンプレートの内容を確認、編集することができます。

テンプレートで使われている言語はVelocityで、if文やJava(JavaScriptではない)の処理を書くこともできるので、かなりカスタマイズできます。

FileTemplateをカスタマイズする

今回はGo言語のgoファイルの生成をプロジェクトに合わせてカスタマイズしてみます。

初期設定の状態で、goファイルを新規作成するとパッケージ名(ディレクトリと同じ名前)が書かれたgoファイルができます。ここではhoge/sample.goを作りました。

同じディレクトリにテスト用のgoファイルhoge/sample_test.goを作ってみます。

sample_test.goファイルが生成されました。ファイルの内容はsample.goと同じpackage hogeになっています。

例えば、プロジェクトの規約にテストコードのパッケージ名には_testを付けるという決まりがあるとします。この場合、既存のテンプレートでは常にpackage hogeとなってしまうので、ファイルを生成した後に手動でpackage hoge_testと書き換える必要があります。

この問題を解決するために、File Templateをカスタマイズしてみましょう。新しいGo Test FileというFile Templateを作ってもいいのですが、今回はファイル名に_testというサフィックスがついていたらテストコードという判定にしました。

テンプレートのコードは以下の様になります。

#if($NAME.endsWith("_test"))
package ${GO_PACKAGE_NAME}_test
#else
package ${GO_PACKAGE_NAME}
#end

テンプレート内で変数を使う場合は${}を付け、括弧内に変数名を書きます。

${GO_PACKAGE_NAME}

最初から定義されている変数はDescriptionのところに説明があるので、参考にして下さい。

if文は以下の様な構文になります。

#if(条件式)
一致した場合
#else
それ以外
#end

条件式はJavaで書くことができます。$NAMEにはStringのファイル名が入っているので、endsWithメソッドで末尾に"_test"が付いているかを判定できます。

ここで変数を使う場合は$変数名と書きます。テンプレート内と違い${変数名}とは書かないので注意して下さい。

#if($NAME.endsWith("_test"))

テンプレートを編集したらOKボタンをクリックして設定を保存し、再度sample.gosample_test.goファイルを作ってみます。

ファイル名に_testサフィックスが付いている場合はpackage hoge_test、ついて居ない場合はpackage hogeと書かれたコードが生成されました。

このようにテンプレートをカスタマイズすることで、ミスを減らし時短にもなるのでオススメです。

複雑なテンプレートを書いてみる

前の章では、packageの部分を変更するだけの簡単なテンプレートを紹介しましたが、もっと複雑な事もできます。

テストファイルの内容はだいたい決まっていて、以下の様なコードを必ず書くとします。

package hoge_test

import "testing"

func TestHoge(t *testing.T) {

}

これを毎回書くのは手間なので、テンプレートに追加します。ここで問題になるのが、スネークケースで書かれているファイル名から、Test関数名をキャメルケースで書かないといけない事です。今回は、スネークケースをキャメルケースに変換する処理をVelocityで書いてみました。

#if($NAME.endsWith("_test"))
    #set($CamelCaseName = "")
    #set($part = "")
    #set($len = $NAME.length() - 5)
    #foreach($part in $NAME.substring(0,$len).split("_"))
        #set($CamelCaseName = "${CamelCaseName}$part.substring(0,1).toUpperCase()$part.substring(1).toLowerCase()")
    #end
package ${GO_PACKAGE_NAME}_test

import "testing"

func Test${CamelCaseName}(t *testing.T) {

}
#else
package ${GO_PACKAGE_NAME}
#end

Velocityで変数に値を代入するには#setを使います。値の部分はJavaの式が使えます。

#set($変数名 = 値)

以下のコードでは、$NAMEの文字数 - 5$len変数に代入しています。

#set($len = $NAME.length() - 5)

配列の各要素に対してループを作るには#foreachを使います。

#foreach($各要素を代入する変数名 in 配列)
#end

以下のコードでは、substringで$NAMEを$len文字に切り詰め、_で区切って配列にしています。

$lenは$NAMEの文字数 - 5なので、$NAMEがhoge_fuga_testなら、substringでhoge_fugaに切り詰め、splitで["hoge", "fuga"]の配列が作られます。

 #foreach($part in $NAME.substring(0,$len).split("_"))

foreachの中では、$CamelCaseNameに先頭1文字を大文字にした単語を追加しています。

#set($CamelCaseName = "${CamelCaseName}$part.substring(0,1).toUpperCase()$part.substring(1).toLowerCase()")

これで、$NAMEの末尾から_testを削除して、キャメルケースに変換した名前が$CamelCaseNameに入ります。

この変更を保存して、またsample_test.goファイルを生成してみます。

ここまで自動生成で生成されるとかなり楽になると思います。

最後に

今回は新しくファイルを生成する時に使われるFile Templateを簡単に紹介しました。IntelliJには他にも便利な機能が沢山あるので色々触ってみると面白いと思います。