Zenn
👼

Go Dead Code を削除するツールを書いた

に公開

バクラク事業CTO 中川佳希です。
この記事では、Dead Code(実行されないコード)を削除するツールについて紹介します。

『Tidy First?』

第2章で、Dead Code について次のように述べられています。

「消そう。以上。実行されないコードは消すだけだ。」

https://www.oreilly.co.jp/books/9784814400911/

Dead Code の背景

大規模なプロジェクトでは、長い年月のリファクタリングや仕様変更の結果、実行されなくなったまま残るコードが増えてしまいます。
個人的にこの Dead Code の問題は、保守性の低下や 認知負荷を高める という品質への悪影響です。
特に昨今では人間だけでなく、AI Coding ツールにとってノイズとなるコンテキストとなり、不要な参照を招くことになります。

golang.org/x/tools/cmd/deadcode

Go 公式ブログでは、下記の記事で Dead Code を検出するツール deadcode を紹介しています。
https://go.dev/blog/deadcode
この記事では、未使用の関数やメソッドを検出する方法、またその内部で利用されている Rapid Type Analysis (RTA) によるアプローチが説明されています。

rdeadcode の紹介

deadcode コマンドはコードを解析して出力するのみです。そこで rdeadcode を実装し、検出された未使用コードを渡すと自動で削除(または書き換え)までを行います。

https://github.com/yyoshiki41/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』で登壇する予定です!現地で参加される方いましたら、ぜひよろしくお願いします。

https://dev-productivity-con.findy-code.io/2025

Platform Engineering 部の紹介

バクラク事業部 Platform Engineering 部では定期的な技術発信を行っています!
AI コーディング、SRE、開発チームエネブルメント、認証などに興味のある方は、ぜひカジュアル面談もお待ちしています。

https://jobs.layerx.co.jp/1cdcdd370bae8002a196e013180c7a4b

https://zenn.dev/layerx/articles/7e9f87fca65e94
https://zenn.dev/layerx/articles/8c5a9a21b2bebe
https://tech.layerx.co.jp/entry/2025/04/10/172743

脚注
  1. Go 以外で記述されたプログラムから行われる呼び出しも考慮していません。 ↩︎

LayerX

Discussion

ログインするとコメントできます