👌

tenten.go 静的解析ナイト【メモ】

2024/10/28に公開

概要

本メモは、tenten さん主催の「tenntenn.go #17 - 静的解析ナイト」に参加したときに
私用に取ったメモです。個人的に気になる部分をメモしただけなので、あしからず。

https://tenntenn.connpass.com/event/333670/

感想

  • 若干開発時に欲しいと感じる静的解析ツールを作成してみるのは楽しそうだと思った
    • ORMなど、Lintでそこまでカスタムできないものは結構遊べそう
  • protobuff便利。いずれ触ってみたい

Go の静的解析

  • 標準ライブラリで大体できる。

  • 準標準、google コアチームの管理しているサブライブラリにもたくさんある

  • Linter:go analysis

  • go vet で複数の Linter が並列で動作する(バイナリ作って、vet で呼び出してもらう)

コード生成 →/go/packages + text/template で出力

go analysis

標準ライブラリでできる、AST と型情報を使って Linter を作る

複数の静的解析ツールの集合体 → go/analysis
コード:Linter = 1:N. 何度もチェックするのは無駄 → まとめるためのもの= analysis

複数の analyzer を1つの analyzer で呼ぶ。

静的解析のフェーズ

AST、 型チェック、静的単一代入形式、
エッジケースまでかつしっかり → 型チェック
調子良い場合 → 静的単一代入形式までやるとよい

型チェック

同じ値になるかわかる
変数が出ると、難しくなる

  1. 識別子の解決(後の変数が前回出た変数なのか、文脈で見る。文字で解析すると、同じものを判別できない。)
  2. 型の推論
  3. 定数の評価

skelton

スケルトンコードジェネレータ。80%の人が作るレベルの同じファイルを作れる

pkg.go.dev でバージョンをクリックすると、変更が見える

https://engineering.mercari.com/blog/entry/20220406-eea588f493/

goplease(gopls)の改造で開発生産性を上げた

  • 静的解析の手動実行めんどい
  • リアルタイムに検出したい

xorm→squirrel への安全な移行を目的に開発。
モデルの定義から、select でワイルドカードを防ぐ(quick fix で実行可能)

テストのテンプレートを自動生成

Go のバージョンを取得するには

種類(1.21 以降)

  • Release: パッチバージョン含む。go1.23rc1 など
  • Language: go1.23
  • go.mod に 1.23 書くと 1.23rc1 とかも含んでしまう。.0 まで書く。どのバージョンが欲しいのか考える必要あり。

go/version

  • runtime.Version→ ビルド時. go version コマンドと同じ
    • バイナリも go version で取得できる。 go version mycmd, -m で環境変数も取れる
    • exec で go env GOVERSION で go.mod に書いてあるバージョンからよしなに取れる
  • go list
    • -m でモジュール情報の取得
    • text/template の形式で書く。
    • go list -m -f "{{.GoVersion}}"→go.mod のバージョンが取れる(toolchain の値ではない)
  • go.mod のパース x/mod/modfile でパースできる
    • go.work のパースもできる

取得するバージョンには気をつける

protoc plugin の作り方(コードの自動生成)

プロト C

  • protobuff で提供されている拡張点
    • protobuff から go に出力できたりする。成果物を作る目的
  • プラグインを使うと、proto を見ればすべてのプログラムのメタデータを管理できる

生成 AI で静的解析ツールの自動生成

GenKit For Go(Firebase, 4o)

Discussion