LoginSignup
10
4

More than 5 years have passed since last update.

君は全てのケースに備えているか? 〜コード静的解析のススメ〜 #golang

Last updated at Posted at 2018-12-23

動機

こんなカンジの型と定数リストがあったとします。

a/a.go
package a

type TestKind int

const (
    TestKindHoge TestKind = iota
    TestKindFuga
    TestKindPiyo
)

いわゆる列挙というか区分みたいなヤツですが、これに対してswitch文とか書きますよね。

sample.go
switch v {
case a.TestKindHoge:
    // do something
case a.TestKindFuga:
    // do something
case a.TestKindPiyo:
    // do something
}

で、実装後に誰か他の開発者が区分が追加したとします。

a/a.go
package a

type TestKind int

const (
    TestKindHoge TestKind = iota
    TestKindFuga
    TestKindPiyo
    TestKindBosukete // Add!
)

その時にswitch文のcaseの追加が漏れていて意図しない挙動になったりすることってないでしょうか。

switch v {
case a.TestKindHoge:
    // do something
case a.TestKindFuga:
    // do something
case a.TestKindPiyo:
    // do something
default:
    panic("unexpected")
}

などとしておけば最悪実行時に検知はできるかもですが、可能ならビルド時に検知したいですよね。

静的解析

go vetgolint みたいなコンパイル前のコード静的解析で検知することができるのでは?
と思い立ちました。

上のパッケージを使用するとGoの静的解析ツールが作成できます(しかもGo1.12からgo vetで呼び出せる様になるらしい)。

ちょうど日本におけるGo静的解析の(というかGoの)伝道師 @tenntenn さんが超わかりやすい記事を書いてくれました!

Goにおける静的解析のモジュール化について
モジュール化された静的解析の実装を追ってみよう

本記事ではanalysisパッケージについての詳細は割愛し、上記を参考に作成したツールを紹介します。

allcasesチェッカー

てな訳で作りました。

allcases

インストール

$ go get github.com/knightso/allcases/cmd/allcases

使い方

$ allcases [-flag] [package] 
  • flagは全て go/analysis から引き継いだもので、必須ではないです。興味ある方は allcases -help でチェックしてください
  • package指定はgo tool準拠です

アノテーション

switch文の前に // allcases というコメントをつけることで、評価する値の型の定数全てのcaseが網羅されるかをチェックします。

sample.go
// allcases
switch v {
case a.TestKindHoge:
    // do something
case a.TestKindFuga:
    // do something
case a.TestKindPiyo:
    // do something
}

出力例↓

/src/sample/sample.go:36:2: no case of a.TestKindBosukete

最後に

個人的にコード静的解析は今後ブームになるのではないかと予想していたのですが、go/analysisパッケージとgo1.12のgo vet組み込みの話を聞いてますます確信に近づきました。(というか自分が遅れてるだけですでに流行ってるってことかな?^^;)

go vetやgolintなどに用意されている汎用的なチェッカーを使うのみでなく、各プロジェクトに特化したカスタムlinterやanalyzerを開発者が気軽につくることで生産性を上げる開発手法が流行る気がしてます。

さいごにもう一つ、今回のツールを作るのに、やはり @tenntenn さん作の commentmap.Analyzer を利用させて貰いました。ありがとうございました。 :bow:
https://github.com/tenntenn/comment
アノテーションコメントの解析を簡単に行うことができるユーティリティAnalyzerです。Analyzer.Requiresフィールドに設定することで利用できます(^^)

10
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
4