goenのコンセプト(go generateはASTベースです)

goen はgo generate用のコード生成ツールを提供しますが、これは可能な限りASTベースで動作するように設計・実装しています。 これはgo generateによって生成される型に対して、同一パッケージ内でユーティリティ的なメソッドを生やす場合に、問題なく再度go generateによりコード生成を行うためだったりします。 go generateにより解析する対象のファイルを除外すれば同様のことをより簡易に実装できることはわかっているのですが、ユーザコード側にそのような制約をあまり発生させたくなかったため、文法しか見ないようASTベースで動作するようになっています。

ASTベースで実装するにあたり、goenのMetaSchemaと仕様差異がなるべく発生しないよう気を遣いました。 手間をかけても、ユーザコードにあまり制約を入れたくなかったのです。

ただ、気にしているのは同一パッケージ内でのことが主で、他のパッケージをimportするような場合、他パッケージはビルド可能であるという前提を置いています。 具体的には、同一パッケージに対する解析には go/ast を用いて、他パッケージに対する解析には go/types を用いています。 その甲斐あって、go generate対象のパッケージが依存する他パッケージに対するimport pathの動的な追加など、個人的に満足いくものになっています。 同名パッケージ(e.g. github.com/google/uuid vs github.com/satori/go.uuid)でも、生成後のコードでは期待通りのパッケージがimportされるようになっています。

そのうち、go generate時に、structのフィールド型に応じたユーティリティメソッドを生やすなど、手をつけらればいいな、と思ってます。