[インデックス 15244] ファイルの概要
このコミットは、Go言語のsyscall
パッケージにおけるドキュメンテーションコメントの扱いを修正するものです。具体的には、//sys
で始まる行がgodoc
によってドキュメンテーションコメントとして解釈されないように変更し、コードの可読性を保ちつつ、godoc
の出力をより一貫性のあるものにすることを目的としています。
変更されたファイルは以下の通りです。
src/pkg/syscall/syscall_bsd.go
: BSD系のシステムコール定義に関連するファイル。src/pkg/syscall/syscall_linux.go
: Linux系のシステムコール定義に関連するファイル。
コミット
- コミットハッシュ:
248d1446b53900b90d1279631a035508942d332c
- Author: Brad Fitzpatrick bradfitz@golang.org
- Date: Thu Feb 14 11:23:58 2013 -0800
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/248d1446b53900b90d1279631a035508942d332c
元コミット内容
syscall: don't make //sys lines be doc comments
Cleans up godoc and makes it consistent. (some had it, some
didn't)
This still keeps the information there, though, for people
looking at the source directly.
R=golang-dev, minux.ma, rsc
CC=golang-dev
https://golang.org/cl/7324056
変更の背景
この変更の背景には、Go言語のドキュメンテーションツールであるgodoc
の挙動と、syscall
パッケージ内の特殊なコメント形式//sys
の相互作用がありました。
syscall
パッケージでは、Goの関数がどのシステムコールに対応するかを示すために、//sys
というプレフィックスを持つコメント行が使用されていました。例えば、//sys open(path string, mode int, perm uint32) (fd int, err error)
のような形式です。
しかし、godoc
は通常、関数や変数などの宣言の直前にあるコメントをその要素のドキュメンテーションコメントとして解釈します。このため、//sys
で始まる行が関数の直前に配置されている場合、godoc
はこれを通常のドキュメンテーションコメントとして扱ってしまい、生成されるドキュメントに不必要な情報が含まれたり、ドキュメントのフォーマットが一貫しなくなったりする問題が発生していました。
コミットメッセージにある「(some had it, some didn't)」という記述は、この//sys
コメントがgodoc
によってドキュメンテーションコメントとして扱われるかどうかが、コードの記述方法によって異なり、一貫性がなかったことを示唆しています。
このコミットは、godoc
の出力を整理し、一貫性を持たせることを目的としています。同時に、//sys
行自体はソースコードを読む開発者にとっては有用な情報であるため、その情報をソースコードから削除することなく、godoc
の解釈から除外する解決策が求められました。
前提知識の解説
Go言語のgodoc
godoc
は、Go言語のソースコードからドキュメンテーションを生成するためのツールです。Go言語では、関数、変数、型、パッケージなどの宣言の直前に記述されたコメントが、その要素のドキュメンテーションとして扱われます。godoc
はこれらのコメントを解析し、HTML形式などで整形されたドキュメントを生成します。これにより、開発者はコードとドキュメントを密接に連携させ、常に最新のドキュメントを維持することができます。
Go言語のsyscall
パッケージ
syscall
パッケージは、Goプログラムからオペレーティングシステムのシステムコールを直接呼び出すための機能を提供します。システムコールは、ファイルI/O、プロセス管理、ネットワーク通信など、OSカーネルが提供する低レベルなサービスを利用するためのインターフェースです。syscall
パッケージは、OSに依存する低レベルな処理をGoから行う際に使用されます。
Go言語におけるドキュメンテーションコメントの規則
Go言語では、ドキュメンテーションコメントは特定の規則に従って記述されます。
- 宣言の直前: ドキュメンテーションコメントは、それが説明する関数、変数、型、またはパッケージの宣言の直前に記述されます。
- 空行: ドキュメンテーションコメントと宣言の間に空行があると、
godoc
はそのコメントをドキュメンテーションコメントとして認識しません。これは、コメントがその宣言に直接関連していることを示すための重要な規則です。 - パッケージコメント: パッケージのドキュメンテーションコメントは、通常、パッケージ宣言の直前に記述され、パッケージの目的や概要を説明します。
このコミットの変更は、特に「空行」の規則を利用して、//sys
行がドキュメンテーションコメントとして解釈されないようにしています。
技術的詳細
このコミットの技術的な核心は、Goのgodoc
ツールがドキュメンテーションコメントをどのように解釈するかという点にあります。godoc
は、コード要素(関数、変数など)の直前にあるコメントブロックをその要素のドキュメンテーションとして扱います。しかし、コメントブロックとコード要素の間に空行が挿入されると、godoc
はそのコメントブロックをドキュメンテーションコメントとは見なしません。
このコミットでは、syscall
パッケージ内のシステムコールを定義するGo関数の直前に記述されていた//sys
で始まる行と、実際のGo関数の間に意図的に空行を挿入しています。
変更前:
//sys open(path string, mode int, perm uint32) (fd int, err error)
func Open(path string, mode int, perm uint32) (fd int, err error) {
// ...
}
変更後:
//sys open(path string, mode int, perm uint32) (fd int, err error)
func Open(path string, mode int, perm uint32) (fd int, err error) {
// ...
}
このわずかな変更(//sys
行の後に空行を追加)により、godoc
は//sys
行をOpen
関数のドキュメンテーションコメントとして認識しなくなります。その結果、godoc
によって生成されるドキュメントには//sys
行が含まれなくなり、ドキュメントの出力がよりクリーンで一貫性のあるものになります。
コミットメッセージにある「This still keeps the information there, though, for people looking at the source directly.」という記述は、この変更が//sys
行自体を削除するものではなく、ソースコードを読む開発者にとっては引き続きシステムコールに関する情報が利用可能であることを強調しています。これは、godoc
の出力とソースコードの可読性の両方を考慮した、バランスの取れた解決策と言えます。
コアとなるコードの変更箇所
このコミットでは、src/pkg/syscall/syscall_bsd.go
とsrc/pkg/syscall/syscall_linux.go
の2つのファイルが変更されています。変更内容は非常にシンプルで、//sys
または//sysnb
で始まる行の直後に空行を追加することです。
src/pkg/syscall/syscall_bsd.go
の変更
--- a/src/pkg/syscall/syscall_bsd.go
+++ b/src/pkg/syscall/syscall_bsd.go
@@ -20,6 +20,7 @@ import (
/*
* Pseudo-system calls
*/
+
// The const provides a compile-time constant so clients
// can adjust to whether there is a working Getwd and avoid
// even linking this function into the binary. See ../os/getwd.go.
この変更は、Pseudo-system calls
セクションの直後にあるコメントブロックと、その後のconst ImplementsGetwd = true
の間に空行を追加しています。これにより、godoc
がこのコメントブロックをImplementsGetwd
定数のドキュメンテーションコメントとして誤って解釈するのを防ぎます。
src/pkg/syscall/syscall_linux.go
の変更
--- a/src/pkg/syscall/syscall_linux.go
+++ b/src/pkg/syscall/syscall_linux.go
@@ -18,16 +18,19 @@ import "unsafe"
*/
//sys open(path string, mode int, perm uint32) (fd int, err error)
+
func Open(path string, mode int, perm uint32) (fd int, err error) {
return open(path, mode|O_LARGEFILE, perm)
}
//sys openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
+
func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
return openat(dirfd, path, flags|O_LARGEFILE, mode)
}
//sysnb pipe(p *[2]_C_int) (err error)
+
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
@@ -40,6 +43,7 @@ func Pipe(p []int) (err error) {
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
+
func Pipe2(p []int, flags int) (err error) {
if len(p) != 2 {
return EINVAL
@@ -52,6 +56,7 @@ func Pipe2(p []int, flags int) (err error) {
}
//sys utimes(path string, times *[2]Timeval) (err error)
+
func Utimes(path string, tv []Timeval) (err error) {
if len(tv) != 2 {
return EINVAL
@@ -60,6 +65,7 @@ func Utimes(path string, tv []Timeval) (err error) {
}
//sys utimensat(dirfd int, path string, times *[2]Timespec) (err error)
+
func UtimesNano(path string, ts []Timespec) (err error) {
if len(ts) != 2 {
return EINVAL
@@ -79,6 +85,7 @@ func UtimesNano(path string, ts []Timespec) (err error) {
}
//sys futimesat(dirfd int, path *byte, times *[2]Timeval) (err error)
+
func Futimesat(dirfd int, path string, tv []Timeval) (err error) {
if len(tv) != 2 {
return EINVAL
@@ -99,6 +106,7 @@ func Futimes(fd int, tv []Timeval) (err error) {
const ImplementsGetwd = true
//sys Getcwd(buf []byte) (n int, err error)
+
func Getwd() (wd string, err error) {
var buf [PathMax]byte
n, err := Getcwd(buf[0:])
@@ -208,6 +216,7 @@ func (w WaitStatus) TrapCause() int {
}
//sys wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error)
+
func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
var status _C_int
wpid, err = wait4(pid, &status, options, rusage)
@@ -809,6 +818,7 @@ func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0)\n func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }\n \n //sys reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error)\n+\n func Reboot(cmd int) (err error) {\n return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, \"\")\n }\n@@ -848,6 +858,7 @@ func ParseDirent(buf []byte, max int, names []string) (consumed int, count int,\n }\n \n //sys mount(source string, target string, fstype string, flags uintptr, data *byte) (err error)\n+\n func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {\n // Certain file systems get rather angry and EINVAL if you give\n // them an empty string of data, rather than NULL.\n```
このファイルでは、`open`, `openat`, `pipe`, `pipe2`, `utimes`, `utimensat`, `futimesat`, `Getcwd`, `wait4`, `reboot`, `mount`といったシステムコールに対応するGo関数の直前にある`//sys`または`//sysnb`行の後に、それぞれ空行が追加されています。
## コアとなるコードの解説
このコミットのコアとなる変更は、Go言語のドキュメンテーションツール`godoc`の挙動を制御するために、コメントとコードの間に空行を挿入するというGoの慣習を利用している点です。
Go言語では、`godoc`がドキュメンテーションコメントとして認識するのは、関数、変数、型などの宣言の直前に、間に空行を挟まずに記述されたコメントブロックのみです。もしコメントブロックと宣言の間に空行が存在すると、`godoc`はそのコメントをドキュメンテーションコメントとは見なしません。
`syscall`パッケージでは、Goの関数がどのシステムコールに対応するかを示すために、`//sys`や`//sysnb`といった特殊なコメント行が使用されていました。これらの行は、Goの関数定義の直前に記述されていたため、`godoc`はこれらを誤ってドキュメンテーションコメントとして解釈し、生成されるドキュメントに含めてしまっていました。これは、`godoc`の出力の一貫性を損ない、場合によっては不要な情報を提供することになっていました。
このコミットでは、`//sys`や`//sysnb`行の直後に空行を挿入することで、これらの行が`godoc`によってドキュメンテーションコメントとして扱われないようにしています。これにより、`godoc`はこれらの行を単なるコード内のコメントとして扱い、生成されるドキュメントからは除外されます。
この変更の利点は以下の通りです。
1. **`godoc`出力の一貫性**: `godoc`によって生成されるドキュメントが、`//sys`行の有無に左右されず、よりクリーンで一貫性のあるものになります。
2. **ドキュメントの正確性**: `//sys`行はシステムコールに関するメタ情報であり、Go関数の公開APIとしてのドキュメンテーションには必ずしも必要ありません。この変更により、`godoc`はGo関数の本来の目的をより正確に反映したドキュメントを生成できます。
3. **ソースコードの可読性の維持**: `//sys`行自体は、ソースコードを直接読む開発者にとって、Go関数がどのシステムコールに対応しているかを理解する上で非常に有用な情報です。この変更は、これらの行を削除することなく、その情報をソースコード内に保持しています。
このように、このコミットはGoのドキュメンテーションシステムの特性を巧みに利用し、`godoc`の出力品質を向上させつつ、ソースコードの有用なメタ情報を維持するという、シンプルながらも効果的な改善を実現しています。
## 関連リンク
* Go CL 7324056: [https://golang.org/cl/7324056](https://golang.org/cl/7324056)
## 参考にした情報源リンク
* Go Doc Comments: [https://go.dev/blog/godoc](https://go.dev/blog/godoc)
* Go `syscall` package documentation: [https://pkg.go.dev/syscall](https://pkg.go.dev/syscall)
* Go `godoc` command documentation: [https://pkg.go.dev/cmd/godoc](https://pkg.go.dev/cmd/godoc)
* Go `doc` package documentation: [https://pkg.go.dev/go/doc](https://pkg.go.dev/go/doc)
* Go `parser` package documentation (for understanding how comments are parsed): [https://pkg.go.dev/go/parser](https://pkg.go.dev/go/parser)
* Go `ast` package documentation (for understanding Abstract Syntax Trees): [https://pkg.go.dev/go/ast](https://pkg.go.dev/go/ast)