2025/06/03
はじめに
Goではgeneratorを用いることで、利用時に見通しの良いメタプログラミングを実現できる。
そこで、ツールを作った時に、生成後のコードを整形する後処理が必要になるので、それをメモにしておく。
後処理の目的
template構文でインデントや改行を気にすると、テンプレートを必要以上に複雑にしてしまうことがある。 また、importの解決をASTで行うのはかなり大変な実装が必要(そう)である。
そこで、Goの標準で使われている実装を利用させてもらうことで、
- コードのフォーマット
- importの整理
をコード内で行う。
これにより、視認性と一貫性があるコードを生成できるようになることが期待される。
コードのフォーマット
Goのコードをフォーマットするには、go/format
パッケージを利用する。
スニペットは以下。
formattedCode, err := format.Source(code)
if err != nil {
log.Fatal(err)
}
importの整理
importの整理には、golang.org/x/tools/imports
パッケージを利用する。
スニペットは以下。
output, err := imports.Process(filePath, code, nil)
if err != nil {
log.Fatal(err)
}
両方とも実行
このように、
package postgenerate
import (
"go/format"
"log"
"golang.org/x/tools/imports"
)
type PostGenerateArgs struct {
OutputFilePath string
Buf []byte
}
func PostGenerate(args PostGenerateArgs) ([]byte, error) {
formattedCode, err := format.Source(args.Buf)
if err != nil {
log.Fatal(err)
}
output, err := imports.Process(args.OutputFilePath, formattedCode, nil)
if err != nil {
log.Fatal(err)
}
return output, nil
}
おわりに
Goは公式がツールで提供しているものにも気軽にアクセスできるので、かなり便利だなと思いました。