golang.tokyo 静的解析Dayでgolang.org/x/tools/go/analysisを使ってみた

golang.org/x/tools/go/analysis 面白そうだなー。 けど触る時間がなかなか取れないなー。 と思っていたらちょうどタイムリーなツイートがあり、

数時間後にこちらの開催が決まりました。

golangtokyo.connpass.com

ということでモクモクとgschonnef.co/go/tools/lintからgolang.org/x/tools/go/analysisへの置き換えをやってきました。

ちなみにgscgolang.tokyo #14のLT*1で紹介した自作のlinterです。

変更点をざっくりまとめると、

  • honnef.co/go/tools/lintではCheckerというinterfaceに実装をするが、golang.org/x/tools/go/analysisではAnalyzerというstructになる
  • honnef.co/go/tools/lintではJobを受け取ってast.Inspectで処理をしていくが、golang.org/x/tools/go/analysisではPassを受け取ってInspector.Preorderで処理をしていく
    • AnalyzerRequiresフィールドに必要な前処理を指定する
    • 次の処理に結果を渡すような作りにすることも可能
  • コマンド本体はlintutil. ProcessFlagSetからmultichecker.Mainになる
    • ただしmainでflagを扱えなくなってしまう!
      • ツール全体でExitCodeを0にするといった制御が不可に...
      • なのでPassReportフィールド(関数)を書き換えることで 無理矢理 実現した
  • テストはhonnef.co/go/tools/lint/testutilgolang.org/x/tools/go/analysis/analysistestになる
    • 使い方はだいたい同じ

といったところです。

統一的なインターフェースになって再利用しやすくなるのもメリットですが、処理速度も向上していて、 手元で3秒くらいかかっていたのが一瞬で終わるようになりました。

今日はまだgolang.org/x/tools/go/analysisを使いこなすところまではいけませんでしたが、とても有意義な時間を過ごせました。

便利なAnalyzerが増えるとみんな幸せになれるのでもっともっと使う人が増えていくと良いですね!