golang.tokyo 静的解析Dayでgolang.org/x/tools/go/analysisを使ってみた
golang.org/x/tools/go/analysis 面白そうだなー。 けど触る時間がなかなか取れないなー。 と思っていたらちょうどタイムリーなツイートがあり、
12/8とかにGoで静的解析を一緒にモクモクやるかいをどこかでやりたいけど、会場がないので、一緒にモクモクしてくれる人とどこか会場を探してます。
— tenntennʕ ◔ϖ◔ʔ ==Go@Goが生きてる (@tenntenn) November 27, 2018
数時間後にこちらの開催が決まりました。
ということでモクモクとgscでhonnef.co/go/tools/lintからgolang.org/x/tools/go/analysis
への置き換えをやってきました。
ちなみにgsc
はgolang.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で処理をしていくAnalyzer
のRequires
フィールドに必要な前処理を指定する- 次の処理に結果を渡すような作りにすることも可能
- コマンド本体はlintutil. ProcessFlagSetからmultichecker.Mainになる
- ただしmainでflagを扱えなくなってしまう!
- ツール全体でExitCodeを0にするといった制御が不可に...
- なので
Pass
のReport
フィールド(関数)を書き換えることで 無理矢理 実現した
- ただしmainでflagを扱えなくなってしまう!
- テストはhonnef.co/go/tools/lint/testutilがgolang.org/x/tools/go/analysis/analysistestになる
- 使い方はだいたい同じ
といったところです。
統一的なインターフェースになって再利用しやすくなるのもメリットですが、処理速度も向上していて、 手元で3秒くらいかかっていたのが一瞬で終わるようになりました。
今日はまだgolang.org/x/tools/go/analysis
を使いこなすところまではいけませんでしたが、とても有意義な時間を過ごせました。
便利なAnalyzer
が増えるとみんな幸せになれるのでもっともっと使う人が増えていくと良いですね!
awesome analyzerを作るという気持ちを示した #golangtokyo
— tenntennʕ ◔ϖ◔ʔ ==Go@Goが生きてる (@tenntenn) December 8, 2018