[インデックス 15415] ファイルの概要
このコミットは、Go言語のコマンドラインツール cmd/go
における vet
コマンドの挙動を修正するものです。具体的には、vet
ツールが型チェックを行うようになったことに伴い、チェック対象のファイルセットを pkg.allgofiles
から pkg.gofiles
に変更することで、無視されるべきファイルが誤ってチェックされる問題を解決しています。
コミット
commit f5afc7d44f5ef20316c9d1d7ec28b45117f3add3
Author: Francisco Souza <franciscossouza@gmail.com>
Date: Mon Feb 25 10:43:04 2013 -0800
cmd/go: fix vet
Now that vet does typechecking, it should use only pkg.gofiles, instead
of pkg.allgofiles. Ignored files should not be checked by vet, because
they wouldn't typecheck.
Fixes #4906.
R=rsc, r
CC=golang-dev
https://golang.org/cl/7401051
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/f5afc7d44f5ef20316c9d1d7ec28b45117f3add3
元コミット内容
cmd/go: fix vet
vet
が型チェックを行うようになったため、pkg.allgofiles
の代わりに pkg.gofiles
のみを使用すべきです。無視されたファイルは vet
によってチェックされるべきではありません。なぜなら、それらは型チェックに合格しないからです。
Fixes #4906.
変更の背景
このコミットの背景には、Go言語の静的解析ツールである go vet
の機能拡張があります。元々 go vet
は、Goのソースコードにおける疑わしい構造や潜在的なエラーを検出するためのツールでしたが、このコミットが作成された時期(2013年2月頃)に、go vet
がより高度な解析を行うために「型チェック」の機能を取り込むようになりました。
型チェック機能が導入される前は、go vet
はファイルの構文解析に基づいて動作することが多く、Goコンパイラが無視するようなファイル(例えば、ビルドタグによって特定の環境でのみコンパイルされるファイルや、テストファイルではないがパッケージに含まれる補助的なファイルなど)も解析対象に含める pkg.allgofiles
を使用しても問題が少なかったと考えられます。
しかし、go vet
が型チェックを行うようになると、コンパイル対象ではないファイル(例えば、特定のOSやアーキテクチャ向けに書かれたが現在のビルド環境では無視されるファイル、あるいは意図的に不完全な状態のコードスニペットなど)を pkg.allgofiles
を通じてチェックしようとすると、それらのファイルが型チェックに失敗し、不必要なエラーや警告を発生させる問題が生じました。これは、開発者が実際にコンパイルして使用するコードではない部分で vet
がエラーを出すため、ノイズとなり、本来修正すべき問題を見落とす原因にもなりかねません。
この問題は、GoのIssueトラッカーで #4906
として報告されており、このコミットはその問題を解決するために作成されました。開発ワークフローにおいて、go vet
はクリーンなコードベースを維持するために重要なツールであるため、その出力が正確で、かつ開発者の意図に沿ったものであることが求められます。この変更は、go vet
の実用性と信頼性を向上させるための重要な修正と言えます。
前提知識の解説
このコミットを理解するためには、以下のGo言語および関連ツールの概念を理解しておく必要があります。
-
go vet
:go vet
は、Go言語のソースコードを静的に解析し、潜在的なバグや疑わしい構造を報告するツールです。例えば、Printf
のフォーマット文字列と引数の不一致、到達不能なコード、ロックの誤用などを検出します。このツールは、コンパイラが検出できないが実行時に問題を引き起こす可能性のあるコードパターンを見つけるのに役立ちます。このコミットの時点では、vet
は型チェック機能を取り込み、より深いレベルでのコード解析が可能になっていました。 -
Goパッケージのビルドプロセスとファイルの種類: Goのビルドシステムは、ソースファイルの種類を区別します。
.go
ファイル: Goのソースコードファイルです。- ビルドタグ (Build Tags): Goのソースファイルには、
// +build linux darwin
のようなビルドタグを含めることができます。これにより、特定のOSやアーキテクチャ、またはカスタムタグが指定された場合にのみ、そのファイルがコンパイル対象に含まれるようになります。ビルドタグに一致しないファイルは、コンパイラによって完全に無視されます。 - テストファイル (
_test.go
): ファイル名が_test.go
で終わるファイルは、テストコードとして扱われます。これらは通常のビルドプロセスではコンパイルされず、go test
コマンドが実行されたときにのみコンパイル・実行されます。
-
pkg.gofiles
とpkg.allgofiles
: Goの内部ビルドシステムやツールがパッケージ内のソースファイルを扱う際に使用する概念です。pkg.gofiles
: これは、現在のビルド環境(OS、アーキテクチャ、ビルドタグなど)に基づいて、実際にコンパイルされるGoのソースファイル(.go
ファイル)のリストを指します。これには、ビルドタグによって無視されるファイルや、_test.go
ファイルは含まれません。つまり、コンパイラが実際に処理するファイルのセットです。pkg.allgofiles
: これは、パッケージディレクトリ内に存在するすべてのGoのソースファイル(.go
ファイル)のリストを指します。これには、ビルドタグによって無視されるファイルや、_test.go
ファイルも含まれる可能性があります。つまり、ディレクトリ内のすべてのGoソースファイルの包括的なリストです。
このコミットの核心は、go vet
が型チェックを行うようになったことで、コンパイラが無視するファイル(pkg.allgofiles
には含まれるが pkg.gofiles
には含まれないファイル)を vet
がチェックしようとすると、それらのファイルは型チェックの前提となるコンパイル環境に存在しないため、型エラーが発生するという問題です。vet
はコンパイラと同様に、実際にビルドされるコードに対してのみ実行されるべきである、という原則に基づいています。
技術的詳細
このコミットの技術的な詳細は、go vet
が静的解析を行う際の「コンテキスト」の重要性に集約されます。
go vet
が型チェックを行うということは、単に構文的なパターンを検出するだけでなく、Goコンパイラがコードを解釈するのと同様に、型情報、スコープ、インポートされたパッケージの定義などを考慮してコードの正当性を検証するようになったことを意味します。
従来の go vet
が pkg.allgofiles
を使用していたのは、おそらく、その時点での vet
の解析が、個々のファイルの構文レベルでのチェックが主であり、ファイルがコンパイル可能であるかどうかの厳密な検証を必要としなかったためです。例えば、Printf
のフォーマット文字列のチェックなどは、そのファイルが実際にコンパイルされるかどうかに関わらず、構文的に有効なGoファイルであれば実行可能でした。
しかし、型チェックが導入されると状況は一変します。型チェックは、コードがGo言語の型システムに準拠しているかを検証するプロセスであり、これには以下の要素が不可欠です。
- 完全な型情報: 変数、関数、構造体などの型が正確に解決されている必要があります。これは、インポートされたパッケージの定義や、同じパッケージ内の他のファイルの定義に依存します。
- コンパイル可能な状態: 型チェックは、コードがコンパイル可能であることを前提とします。もしファイルがビルドタグによって現在の環境でコンパイル対象から外されている場合、そのファイルはコンパイラによって処理されず、結果として型情報が不完全または存在しない状態になります。
pkg.allgofiles
には、ビルドタグによって現在のビルド環境ではコンパイルされないファイルが含まれる可能性があります。これらのファイルは、コンパイラが無視するため、それらのファイル内のコードは型解決されません。go vet
がこれらの「無視されたファイル」に対して型チェックを実行しようとすると、型情報が欠落しているため、本来エラーではないコードに対しても型エラーを報告してしまいます。これは、vet
の出力に誤った情報(ノイズ)を混入させ、開発者が本当に修正すべき問題を見つけにくくします。
この問題を解決するために、go vet
は pkg.gofiles
を使用するように変更されました。pkg.gofiles
は、現在のビルド環境で実際にコンパイルされるGoソースファイルのセットを正確に表します。これにより、go vet
はコンパイラが処理するのと同じコードセットに対して型チェックを実行するため、vet
の出力はより正確で、開発者の意図に沿ったものになります。つまり、vet
は「実際にビルドされるコード」に対してのみ警告を出すようになり、開発者はその警告に集中できるようになります。
この変更は、Goツールの設計哲学である「ツールはコンパイラと協調して動作し、開発者に有用な情報のみを提供するべきである」という原則に合致しています。
コアとなるコードの変更箇所
変更は src/cmd/go/vet.go
ファイルの1箇所のみです。
--- a/src/cmd/go/vet.go
+++ b/src/cmd/go/vet.go
@@ -32,6 +32,6 @@ func runVet(cmd *Command, args []string) {
// Use pkg.gofiles instead of pkg.Dir so that
// the command only applies to this package,
// not to packages in subdirectories.
- run(tool("vet"), relPaths(pkg.allgofiles))
+ run(tool("vet"), relPaths(pkg.gofiles))
}
}
コアとなるコードの解説
変更された行は src/cmd/go/vet.go
内の runVet
関数の一部です。
元のコード:
run(tool("vet"), relPaths(pkg.allgofiles))
変更後のコード:
run(tool("vet"), relPaths(pkg.gofiles))
この変更は、go vet
ツールを実行する際に、引数として渡すファイルのリストを pkg.allgofiles
から pkg.gofiles
に切り替えるものです。
tool("vet")
: これはgo vet
実行可能ファイルのパスを取得するヘルパー関数です。relPaths(...)
: これは、与えられたファイルパスのリストを、現在の作業ディレクトリからの相対パスに変換するヘルパー関数です。pkg.allgofiles
: 変更前は、パッケージ内のすべてのGoソースファイル(ビルドタグで無視されるファイルやテストファイルも含む可能性のある包括的なリスト)がvet
に渡されていました。pkg.gofiles
: 変更後は、現在のビルド環境で実際にコンパイルされるGoソースファイルのみがvet
に渡されます。
この一行の変更がもたらす影響は非常に大きく、go vet
が型チェックを行うようになったという前提と合わせて考えると、以下のようになります。
- 正確性の向上:
vet
は、実際にコンパイルされるコードに対してのみ型チェックを行うようになります。これにより、ビルドタグによって無視されるファイルや、現在の環境ではコンパイルされないファイルに起因する誤った型エラーや警告が排除されます。 - ノイズの削減: 開発者は、実際にビルドされるコードに関する
vet
の警告に集中できるようになり、開発ワークフローの効率が向上します。 - コンパイラとの整合性:
vet
の動作がGoコンパイラの動作とより密接に連携するようになります。コンパイラが無視するファイルはvet
も無視する、という一貫した挙動が実現されます。
この修正は、go vet
がより強力な解析能力(型チェック)を獲得したことに伴い、その解析対象を適切に限定することで、ツールの有用性と信頼性を最大限に引き出すための、まさに「修正」と呼ぶにふさわしい変更です。
関連リンク
- GitHubコミットページ: https://github.com/golang/go/commit/f5afc7d44f5ef20316c9d1d7ec28b45117f3add3
- Go Issue #4906: https://github.com/golang/go/issues/4906
- Go CL 7401051: https://golang.org/cl/7401051
参考にした情報源リンク
- Go言語の公式ドキュメント(
go vet
、ビルドタグ、パッケージ構造に関する情報) - Go言語のIssueトラッカー(特にIssue #4906の議論)
- Go言語のソースコード(
cmd/go
およびgo/build
パッケージの関連部分) - Go言語に関する技術ブログや解説記事(
go vet
の機能や進化に関するもの)
[インデックス 15415] ファイルの概要
このコミットは、Go言語のコマンドラインツール cmd/go
における vet
コマンドの挙動を修正するものです。具体的には、vet
ツールがより高度な型関連のチェックを行うようになったことに伴い、チェック対象のファイルセットを pkg.allgofiles
から pkg.gofiles
に変更することで、無視されるべきファイルが誤ってチェックされる問題を解決しています。
コミット
commit f5afc7d44f5ef20316c9d1d7ec28b45117f3add3
Author: Francisco Souza <franciscossouza@gmail.com>
Date: Mon Feb 25 10:43:04 2013 -0800
cmd/go: fix vet
Now that vet does typechecking, it should use only pkg.gofiles, instead
of pkg.allgofiles. Ignored files should not be checked by vet, because
they wouldn't typecheck.
Fixes #4906.
R=rsc, r
CC=golang-dev
https://golang.org/cl/7401051
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/f5afc7d44f5ef20316c9d1d7ec28b45117f3add3
元コミット内容
cmd/go: fix vet
vet
が型チェックを行うようになったため、pkg.allgofiles
の代わりに pkg.gofiles
のみを使用すべきです。無視されたファイルは vet
によってチェックされるべきではありません。なぜなら、それらは型チェックに合格しないからです。
Fixes #4906.
変更の背景
このコミットの背景には、Go言語の静的解析ツールである go vet
の機能拡張があります。元々 go vet
は、Goのソースコードにおける疑わしい構造や潜在的なエラーを検出するためのツールでしたが、このコミットが作成された時期(2013年2月頃)に、go vet
がより高度な解析を行うために「型チェック」の側面を取り込むようになりました。これは、Printf
のフォーマット文字列と引数の不一致を検証するなど、型情報に基づいたより深い分析を可能にするものでした。
型関連のチェック機能が導入される前は、go vet
はファイルの構文解析に基づいて動作することが多く、Goコンパイラが無視するようなファイル(例えば、ビルドタグによって特定の環境でのみコンパイルされるファイルや、テストファイルではないがパッケージに含まれる補助的なファイルなど)も解析対象に含める pkg.allgofiles
を使用しても問題が少なかったと考えられます。
しかし、go vet
が型関連のチェックを強化するようになると、コンパイル対象ではないファイル(例えば、特定のOSやアーキテクチャ向けに書かれたが現在のビルド環境では無視されるファイル、あるいは意図的に不完全な状態のコードスニペットなど)を pkg.allgofiles
を通じてチェックしようとすると、それらのファイルは型チェックの前提となるコンパイル環境に存在しないため、不必要なエラーや警告を発生させる問題が生じました。これは、開発者が実際にコンパイルして使用するコードではない部分で vet
がエラーを出すため、ノイズとなり、本来修正すべき問題を見落とす原因にもなりかねません。
この問題は、GoのIssueトラッカーで #4906
として報告されており、このコミットはその問題を解決するために作成されました。開発ワークフローにおいて、go vet
はクリーンなコードベースを維持するために重要なツールであるため、その出力が正確で、かつ開発者の意図に沿ったものであることが求められます。この変更は、go vet
の実用性と信頼性を向上させるための重要な修正と言えます。
前提知識の解説
このコミットを理解するためには、以下のGo言語および関連ツールの概念を理解しておく必要があります。
-
go vet
:go vet
は、Go言語のソースコードを静的に解析し、潜在的なバグや疑わしい構造を報告するツールです。例えば、Printf
のフォーマット文字列と引数の不一致、到達不能なコード、ロックの誤用などを検出します。このツールは、コンパイラが検出できないが実行時に問題を引き起こす可能性のあるコードパターンを見つけるのに役立ちます。このコミットの時点では、vet
は型情報に基づいたより深い解析が可能になっていました。 -
Goパッケージのビルドプロセスとファイルの種類: Goのビルドシステムは、ソースファイルの種類を区別します。
.go
ファイル: Goのソースコードファイルです。- ビルドタグ (Build Tags): Goのソースファイルには、
// +build linux darwin
のようなビルドタグを含めることができます。これにより、特定のOSやアーキテクチャ、またはカスタムタグが指定された場合にのみ、そのファイルがコンパイル対象に含まれるようになります。ビルドタグに一致しないファイルは、コンパイラによって完全に無視されます。 - テストファイル (
_test.go
): ファイル名が_test.go
で終わるファイルは、テストコードとして扱われます。これらは通常のビルドプロセスではコンパイルされず、go test
コマンドが実行されたときにのみコンパイル・実行されます。
-
pkg.gofiles
とpkg.allgofiles
: Goの内部ビルドシステムやツールがパッケージ内のソースファイルを扱う際に使用する概念です。pkg.gofiles
: これは、現在のビルド環境(OS、アーキテクチャ、ビルドタグなど)に基づいて、実際にコンパイルされるGoのソースファイル(.go
ファイル)のリストを指します。これには、ビルドタグによって無視されるファイルや、_test.go
ファイルは含まれません。つまり、コンパイラが実際に処理するファイルのセットです。pkg.allgofiles
: これは、パッケージディレクトリ内に存在するすべてのGoのソースファイル(.go
ファイル)のリストを指します。これには、ビルドタグによって無視されるファイルや、_test.go
ファイルも含まれる可能性があります。つまり、ディレクトリ内のすべてのGoソースファイルの包括的なリストです。
このコミットの核心は、go vet
が型関連のチェックを行うようになったことで、コンパイラが無視するファイル(pkg.allgofiles
には含まれるが pkg.gofiles
には含まれないファイル)を vet
がチェックしようとすると、それらのファイルは型チェックの前提となるコンパイル環境に存在しないため、型エラーが発生するという問題です。vet
はコンパイラと同様に、実際にビルドされるコードに対してのみ実行されるべきである、という原則に基づいています。
技術的詳細
このコミットの技術的な詳細は、go vet
が静的解析を行う際の「コンテキスト」の重要性に集約されます。
go vet
が型関連のチェックを行うということは、単に構文的なパターンを検出するだけでなく、Goコンパイラがコードを解釈するのと同様に、型情報、スコープ、インポートされたパッケージの定義などを考慮してコードの正当性を検証するようになったことを意味します。このコミットが作成された2013年2月時点では、go/types
パッケージのような完全な型チェッカーがGoの標準ライブラリに導入される前(go/types
はGo 1.5で導入)でしたが、vet
は既に Printf
のフォーマット文字列の検証など、型情報に依存する高度なチェックを実行していました。
従来の go vet
が pkg.allgofiles
を使用していたのは、おそらく、その時点での vet
の解析が、個々のファイルの構文レベルでのチェックが主であり、ファイルがコンパイル可能であるかどうかの厳密な検証を必要としなかったためです。例えば、Printf
のフォーマット文字列のチェックなどは、そのファイルが実際にコンパイルされるかどうかに関わらず、構文的に有効なGoファイルであれば実行可能でした。
しかし、型関連のチェックが強化されると状況は一変します。型関連のチェックは、コードがGo言語の型システムに準拠しているかを検証するプロセスであり、これには以下の要素が不可欠です。
- 完全な型情報: 変数、関数、構造体などの型が正確に解決されている必要があります。これは、インポートされたパッケージの定義や、同じパッケージ内の他のファイルの定義に依存します。
- コンパイル可能な状態: 型関連のチェックは、コードがコンパイル可能であることを前提とします。もしファイルがビルドタグによって現在の環境でコンパイル対象から外されている場合、そのファイルはコンパイラによって処理されず、結果として型情報が不完全または存在しない状態になります。
pkg.allgofiles
には、ビルドタグによって現在のビルド環境ではコンパイルされないファイルが含まれる可能性があります。これらのファイルは、コンパイラが無視するため、それらのファイル内のコードは型解決されません。go vet
がこれらの「無視されたファイル」に対して型関連のチェックを実行しようとすると、型情報が欠落しているため、本来エラーではないコードに対しても型エラーを報告してしまいます。これは、vet
の出力に誤った情報(ノイズ)を混入させ、開発者が本当に修正すべき問題を見つけにくくします。
この問題を解決するために、go vet
は pkg.gofiles
を使用するように変更されました。pkg.gofiles
は、現在のビルド環境で実際にコンパイルされるGoソースファイルのセットを正確に表します。これにより、go vet
はコンパイラが処理するのと同じコードセットに対して型関連のチェックを実行するため、vet
の出力はより正確で、開発者の意図に沿ったものになります。つまり、vet
は「実際にビルドされるコード」に対してのみ警告を出すようになり、開発者はその警告に集中できるようになります。
この変更は、Goツールの設計哲学である「ツールはコンパイラと協調して動作し、開発者に有用な情報のみを提供するべきである」という原則に合致しています。
コアとなるコードの変更箇所
変更は src/cmd/go/vet.go
ファイルの1箇所のみです。
--- a/src/cmd/go/vet.go
+++ b/cmd/go/vet.go
@@ -32,6 +32,6 @@ func runVet(cmd *Command, args []string) {
// Use pkg.gofiles instead of pkg.Dir so that
// the command only applies to this package,
// not to packages in subdirectories.
- run(tool("vet"), relPaths(pkg.allgofiles))
+ run(tool("vet"), relPaths(pkg.gofiles))
}
}
コアとなるコードの解説
変更された行は src/cmd/go/vet.go
内の runVet
関数の一部です。
元のコード:
run(tool("vet"), relPaths(pkg.allgofiles))
変更後のコード:
run(tool("vet"), relPaths(pkg.gofiles))
この変更は、go vet
ツールを実行する際に、引数として渡すファイルのリストを pkg.allgofiles
から pkg.gofiles
に切り替えるものです。
tool("vet")
: これはgo vet
実行可能ファイルのパスを取得するヘルパー関数です。relPaths(...)
: これは、与えられたファイルパスのリストを、現在の作業ディレクトリからの相対パスに変換するヘルパー関数です。pkg.allgofiles
: 変更前は、パッケージ内のすべてのGoソースファイル(ビルドタグで無視されるファイルやテストファイルも含む可能性のある包括的なリスト)がvet
に渡されていました。pkg.gofiles
: 変更後は、現在のビルド環境で実際にコンパイルされるGoソースファイルのみがvet
に渡されます。
この一行の変更がもたらす影響は非常に大きく、go vet
が型関連のチェックを行うようになったという前提と合わせて考えると、以下のようになります。
- 正確性の向上:
vet
は、実際にコンパイルされるコードに対してのみ型関連のチェックを行うようになります。これにより、ビルドタグによって無視されるファイルや、現在の環境ではコンパイルされないファイルに起因する誤った型エラーや警告が排除されます。 - ノイズの削減: 開発者は、実際にビルドされるコードに関する
vet
の警告に集中できるようになり、開発ワークフローの効率が向上します。 - コンパイラとの整合性:
vet
の動作がGoコンパイラの動作とより密接に連携するようになります。コンパイラが無視するファイルはvet
も無視する、という一貫した挙動が実現されます。
この修正は、go vet
がより強力な解析能力(型関連のチェック)を獲得したことに伴い、その解析対象を適切に限定することで、ツールの有用性と信頼性を最大限に引き出すための、まさに「修正」と呼ぶにふさわしい変更です。
関連リンク
- GitHubコミットページ: https://github.com/golang/go/commit/f5afc7d44f5ef20316c9d1d7ec28b45117f3add3
- Go Issue #4906: https://github.com/golang/go/issues/4906
- Go CL 7401051: https://golang.org/cl/7401051
参考にした情報源リンク
- Go言語の公式ドキュメント(
go vet
、ビルドタグ、パッケージ構造に関する情報) - Go言語のIssueトラッカー(特にIssue #4906の議論)
- Go言語のソースコード(
cmd/go
およびgo/build
パッケージの関連部分) - Go言語に関する技術ブログや解説記事(
go vet
の機能や進化に関するもの) - Web検索: "Go vet typechecking introduction date" (2013年2月時点での
vet
の型関連チェックの状況を把握するため)