Go Dead Code を削除するツールを書いた
バクラク事業CTO 中川佳希です。
この記事では、Dead Code(実行されないコード)を削除するツールについて紹介します。
『Tidy First?』
第2章で、Dead Code について次のように述べられています。
「消そう。以上。実行されないコードは消すだけだ。」
Dead Code の背景
大規模なプロジェクトでは、長い年月のリファクタリングや仕様変更の結果、実行されなくなったまま残るコードが増えてしまいます。
個人的にこの Dead Code の問題は、保守性の低下や 認知負荷を高める という品質への悪影響です。
特に昨今では人間だけでなく、AI Coding ツールにとってノイズとなるコンテキストとなり、不要な参照を招くことになります。
golang.org/x/tools/cmd/deadcode
Go 公式ブログでは、下記の記事で Dead Code を検出するツール deadcode
を紹介しています。
この記事では、未使用の関数やメソッドを検出する方法、またその内部で利用されている Rapid Type Analysis (RTA) によるアプローチが説明されています。
rdeadcode
の紹介
deadcode
コマンドはコードを解析して出力するのみです。そこで rdeadcode
を実装し、検出された未使用コードを渡すと自動で削除(または書き換え)までを行います。
インストール
go install github.com/yyoshiki41/rdeadcode@latest
特徴
-
出力のパースと自動削除
-
deadcode
の JSON 形式の出力を利用して、対象のソースコードから未使用の関数を除去できます。
-
-
goimports や go/format での整形
- 不要な関数や変数の削除後、利用されていない import パッケージが残らないように整形して、書き換えます。
-
ファイル単位、関数単位の削除オプション
-
-file
や-function
オプションを使えば、特定のファイル内または特定の関数だけを削除できます。 - 上のコード整形も一緒に行ってくれるため、リファクタリングツールとして便利です。
-
使用例
deadcode
コマンドで JSON 形式で出力し、その出力を rdeadcode
に渡します。
deadcode -json -test ./path/to/your/project | rdeadcode
rdeadcode
のオプション
$ rdeadcode --help
Usage of rdeadcode:
-file string
File to remove function from
-function string
Function to remove
-ignore string
Ignore files matching glob pattern
-json string
JSON file generated by deadcode
既に保存された JSON ファイルを使う場合
rdeadcode -json deadcode.json
特定のファイルから特定の関数を削除する場合
rdeadcode -file path/to/your/file.go -function deadFunction
注意点: インターフェースを満たすメソッド実装の誤検知
Go 公式ブログでも言及されている通りすべての静的解析ツールは、関数値やインターフェース値、リフレクションを用いた動的挙動の完全な把握は困難であり、不完全な近似値を生成するに留まります。deadcode
は健全な(保守より)設計となっており、ある関数が Dead Code として報告された場合、それはこれらの動的メカニズムを通じても呼び出されることがないことを意味します(一方で実際には呼び出されないにもかかわらず、報告されない可能性があります)。[1]
The deadcode tool is no exception: it must approximate the set of targets of dynamic calls through function and interface values or using reflection. In this respect, the tool is sound. In other words, if it reports a function as dead code, it means the function cannot be called even through these dynamic mechanisms. However the tool may fail to report some functions that in fact can never be executed.
しかし、公式ブログで言及されていない Dead Code として削除されるケースもあります。プロジェクト外部のインターフェイスを満たすためのメソッドがプロジェクトで使用されていない場合に Dead Code として報告されます。そのため、報告されたコードが外部パッケージの必要なインターフェースを満たすためのものである場合があります。
これは識別することが出来ないため、プロジェクト内でコンパイル時にチェックするよう(Compile-time Compliance)に実装してください。
// Verify interface compliance at compile time
var _ fmt.Stringer = myString{}
type myString struct {
Value string
}
func (s myString) String() string {
return s.Value
}
実際に使った例
500行ほど消した。
Goはコンパイルが通れば、安心してマージできる。素晴らしい!
最後に
2025年7月に行われる開発生産性Conferenceに Kent Beck 氏が来ることもあり、『Tidy First?』を読んで、開発者としての所作を改めて意識させられ、(このツールを書いたのは昨年5月でしたが、今になって)この記事を書くに至りました。
私も Conference 1日目に『AIエージェントが変える開発組織のEnabling』で登壇する予定です!現地で参加される方いましたら、ぜひよろしくお願いします。
Platform Engineering 部の紹介
バクラク事業部 Platform Engineering 部では定期的な技術発信を行っています!
AI コーディング、SRE、開発チームエネブルメント、認証などに興味のある方は、ぜひカジュアル面談もお待ちしています。
-
Go 以外で記述されたプログラムから行われる呼び出しも考慮していません。 ↩︎
Discussion