[インデックス 11480] ファイルの概要
このコミットは、Go言語のドキュメンテーションツールであるgodoc
に、URLパラメータm=methods
を追加するものです。この新しいモードを有効にすると、godoc
が生成するドキュメンテーションにおいて、エクスポートされていない匿名フィールドのメソッドを含む、すべての埋め込みメソッドが表示されるようになります。
コミット
commit ff451e8670cff9f825706b193657c8b2129310f8
Author: Robert Griesemer <gri@golang.org>
Date: Mon Jan 30 14:07:50 2012 -0800
godoc: add URL mode m=methods
If set, all methods are shown, not just those
of non-exported anonynous fields.
This change will only become functional once
CL 5576057 is submitted.
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5599048
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/ff451e8670cff9f825706b193657c8b2129310f8
元コミット内容
godoc
ツールにm=methods
という新しいURLモードを追加します。このモードが設定されると、エクスポートされていない匿名フィールドのメソッドだけでなく、すべてのメソッドが表示されるようになります。この変更は、関連する変更リスト(CL 5576057)がコミットされて初めて機能します。
変更の背景
godoc
はGo言語のコードからドキュメンテーションを自動生成する非常に便利なツールです。しかし、Goの構造体(struct)における匿名フィールド(embedded fields)とメソッドの埋め込み(method embedding)の仕組みにより、特定の状況下では、開発者が期待するすべてのメソッドがドキュメンテーションに表示されないという問題がありました。
特に、エクスポートされていない(unexported)匿名フィールドに定義されたメソッドは、そのフィールドが埋め込まれた構造体から呼び出すことが可能ですが、godoc
のデフォルトの挙動では、これらのメソッドがドキュメンテーションから除外される傾向がありました。これは、通常、エクスポートされていない要素は内部実装の詳細と見なされ、公開APIの一部ではないという考え方に基づいています。
しかし、場合によっては、これらの「隠れた」メソッドもドキュメンテーションに含めることが望ましいことがあります。例えば、ライブラリの内部構造を深く理解したい開発者や、特定のデバッグシナリオにおいて、すべてのメソッドの存在を把握したい場合などです。
このコミットは、このようなニーズに応えるため、ユーザーが明示的にすべてのメソッドを表示させるためのオプションを提供することを目的としています。これにより、godoc
の柔軟性が向上し、より詳細なドキュメンテーションの閲覧が可能になります。
前提知識の解説
1. godoc
とは
godoc
は、Go言語のソースコードからドキュメンテーションを生成し、ウェブサーバーとして提供するツールです。Goのコードは、特定のコメント規約(Go Docコメント)に従って記述することで、godoc
によって自動的に解析され、整形されたドキュメンテーションとして表示されます。これにより、開発者はコードとドキュメンテーションを密接に連携させ、常に最新の状態に保つことができます。
2. Go言語の匿名フィールドとメソッドの埋め込み
Go言語の構造体は、他の構造体を匿名フィールドとして埋め込むことができます。これにより、埋め込まれた構造体のフィールドやメソッドが、外側の構造体に「昇格(promote)」され、あたかも外側の構造体自身のメンバーであるかのように直接アクセスできるようになります。
例:
type Inner struct {
value int
}
func (i Inner) GetValue() int {
return i.value
}
type Outer struct {
Inner // 匿名フィールドとしてInnerを埋め込み
name string
}
func main() {
o := Outer{Inner: Inner{value: 10}, name: "test"}
fmt.Println(o.GetValue()) // OuterのインスタンスからInnerのメソッドを直接呼び出せる
}
この仕組みは、Goにおけるオブジェクト指向的な「継承」に似た機能を提供しますが、実際にはコンポジション(合成)の一種です。
3. エクスポートされた識別子とエクスポートされていない識別子
Go言語では、識別子(変数名、関数名、型名など)の最初の文字が大文字である場合、その識別子は「エクスポートされている(exported)」と見なされ、パッケージ外からアクセス可能です。最初の文字が小文字である場合、「エクスポートされていない(unexported)」と見なされ、その識別子は定義されたパッケージ内でのみアクセス可能です。
godoc
は通常、公開APIを重視するため、エクスポートされた識別子のみをドキュメンテーションに含める傾向があります。しかし、匿名フィールドのメソッドの場合、埋め込まれたフィールド自体がエクスポートされていなくても、そのメソッドは外側の構造体から呼び出し可能であるため、ドキュメンテーションの対象とするかどうかが問題となります。
4. doc
パッケージ
Goの標準ライブラリには、go/doc
パッケージが存在します。このパッケージは、Goのソースコードを解析し、ドキュメンテーションツリーを構築するための低レベルな機能を提供します。godoc
ツールはこのgo/doc
パッケージを利用して、実際のドキュメンテーション情報を抽出しています。
技術的詳細
このコミットは、godoc
のウェブインターフェースにおける表示モードを制御するための新しいURLパラメータm=methods
を導入します。この機能を実現するために、主に以下の2つのファイルが変更されています。
-
src/cmd/godoc/doc.go
:- このファイルは、
godoc
のURLパラメータm
に関するドキュメンテーションを記述しています。 - 変更点として、
m
パラメータのオプションリストにmethods
が追加され、「エクスポートされていない匿名フィールドのメソッドだけでなく、すべての埋め込みメソッドを表示する」という説明が加えられています。これはユーザー向けの機能説明となります。
- このファイルは、
-
src/cmd/godoc/godoc.go
:- このファイルは
godoc
の主要なロジックを含んでいます。 PageInfoMode
列挙型へのallMethods
フラグの追加:PageInfoMode
は、godoc
がページ情報を生成する際の様々な表示モードをビットフラグとして定義する列挙型です。ここにallMethods
という新しいフラグが追加されました。const ( noFiltering PageInfoMode = 1 << iota // do not filter exports allMethods // show all embedded methods showSource // show source code, do not extract documentation noHtml // show result in textual form, do not generate HTML flatDir // show directory in a flat (non-indented) manner )
modeNames
マップへの"methods"
エントリの追加:modeNames
マップは、URLパラメータの文字列(例: "all", "src")と、それに対応する内部のPageInfoMode
フラグをマッピングします。ここに"methods": allMethods
というエントリが追加され、URLでm=methods
が指定された場合に、内部的にallMethods
フラグが設定されるようになります。var modeNames = map[string]PageInfoMode{ "all": noFiltering, "methods": allMethods, // <-- New entry "src": showSource, "text": noHtml, "flat": flatDir, }
getPageInfo
関数でのdoc.AllMethods
フラグの適用:getPageInfo
関数は、HTTPリクエストからページ情報を抽出し、go/doc
パッケージのdoc.New
関数に渡すためのモードを決定します。 この関数内で、新しく追加されたallMethods
フラグがチェックされます。もしmode
変数にallMethods
フラグが立っていれば(つまり、URLでm=methods
が指定されていれば)、doc.AllMethods
というフラグがm
変数にビットOR演算で追加されます。
ここで重要なのは、if mode&allMethods != 0 { m |= doc.AllMethods } pdoc = doc.New(pkg, path.Clean(relpath), m) // no trailing '/' in importpath
doc.AllMethods
というフラグがgo/doc
パッケージ(このコミットの時点ではまだ存在しないが、関連するCL 5576057で追加される)に定義されていることです。このコミットは、godoc
がこの新しいdoc.AllMethods
フラグを認識し、それをgo/doc
パッケージに渡すための橋渡しをする役割を担っています。
- このファイルは
関連する変更リスト (CL 5576057)
コミットメッセージにも明記されている通り、この変更は単独では機能しません。このコミットが完全に機能するためには、別の変更リスト(Change List)であるCL 5576057
がGoのリポジトリにコミットされる必要があります。
CL 5576057
は、go/doc
パッケージにAllMethods
という新しいフラグを導入するものです。このフラグは、doc.New
関数に渡されることで、go/doc
パッケージがドキュメンテーションを生成する際に、エクスポートされていない匿名フィールドのメソッドを含むすべてのメソッドを考慮するように指示します。
つまり、このコミット(ff451e8670cff9f825706b193657c8b2129310f8)はgodoc
のユーザーインターフェースと内部ロジックを準備し、CL 5576057
はドキュメンテーション解析のコア部分に実際の機能を追加するという、2段階の変更の一部となっています。
コアとなるコードの変更箇所
src/cmd/godoc/doc.go
--- a/src/cmd/godoc/doc.go
+++ b/src/cmd/godoc/doc.go
@@ -131,7 +131,8 @@ shown, and only an identifier index but no full text search index is created.
The presentation mode of web pages served by godoc can be controlled with the
"m" URL parameter; it accepts a comma-separated list of flag names as value:
- all show documentation for all (not just exported) declarations
+ all show documentation for all declarations, not just the exported ones
+ methods show all embedded methods, not just those of unexported anonymous fields
src show the original source code rather then the extracted documentation
text present the page in textual (command-line) form rather than HTML
flat present flat (not indented) directory listings using full paths
src/cmd/godoc/godoc.go
--- a/src/cmd/godoc/godoc.go
+++ b/src/cmd/godoc/godoc.go
@@ -867,6 +867,7 @@ type PageInfoMode uint
const (
noFiltering PageInfoMode = 1 << iota // do not filter exports
+ allMethods // show all embedded methods
showSource // show source code, do not extract documentation
noHtml // show result in textual form, do not generate HTML
flatDir // show directory in a flat (non-indented) manner
@@ -874,10 +875,11 @@ const (
// modeNames defines names for each PageInfoMode flag.
var modeNames = map[string]PageInfoMode{
- "all": noFiltering,
- "src": showSource,
- "text": noHtml,
- "flat": flatDir,
+ "all": noFiltering,
+ "methods": allMethods, // <-- New entry
+ "src": showSource,
+ "text": noHtml,
+ "flat": flatDir,
}
// getPageInfoMode computes the PageInfoMode flags by analyzing the request
@@ -1088,6 +1090,9 @@ func (h *httpHandler) getPageInfo(abspath, relpath, pkgname string, mode PageInf
if mode&noFiltering != 0 {
m = doc.AllDecls
}
+ if mode&allMethods != 0 {
+ m |= doc.AllMethods // <-- Apply doc.AllMethods flag
+ }
pdoc = doc.New(pkg, path.Clean(relpath), m) // no trailing '/' in importpath
} else {
// show source code
コアとなるコードの解説
-
src/cmd/godoc/doc.go
の変更:- この変更は、
godoc
のウェブインターフェースのヘルプテキストを更新するものです。 m
URLパラメータの利用可能なオプションとして、新しくmethods
が追加され、その機能(「エクスポートされていない匿名フィールドのメソッドだけでなく、すべての埋め込みメソッドを表示する」)が説明されています。これにより、ユーザーはこの新機能の存在と使い方をgodoc
自身のドキュメンテーションを通じて知ることができます。
- この変更は、
-
src/cmd/godoc/godoc.go
の変更:PageInfoMode
へのallMethods
の追加:PageInfoMode
は、godoc
がドキュメンテーションを生成する際の内部的な表示モードを管理するためのビットフラグの集合です。allMethods
という新しいフラグが追加され、これが設定されると、すべての埋め込みメソッドを表示するという意図が示されます。modeNames
マップへの"methods"
エントリの追加:modeNames
は、URLクエリパラメータの文字列(例:m=methods
のmethods
部分)を、対応するPageInfoMode
のビットフラグにマッピングするためのマップです。このエントリが追加されたことで、ユーザーがURLでm=methods
を指定すると、godoc
の内部でallMethods
フラグが有効になります。getPageInfo
関数でのロジック追加:getPageInfo
関数は、HTTPリクエストから現在の表示モードを解析し、go/doc
パッケージのdoc.New
関数に渡すための適切なフラグを構築します。if mode&allMethods != 0
という条件文が追加されています。これは、現在のmode
(URLパラメータから解析されたもの)にallMethods
フラグが立っているかどうかをチェックします。- もし
allMethods
フラグが立っていれば、m |= doc.AllMethods
という行が実行されます。これは、doc.New
関数に渡される最終的なモード変数m
に、go/doc
パッケージが提供するdoc.AllMethods
フラグをビットOR演算で追加するものです。 - この
doc.AllMethods
フラグがgo/doc
パッケージに渡されることで、go/doc
パッケージは、通常はフィルタリングされるエクスポートされていない匿名フィールドのメソッドもドキュメンテーションに含めるようになります。
これらの変更により、godoc
はURLパラメータを通じて、より詳細なメソッド表示を制御できるようになり、Go言語のドキュメンテーションの柔軟性が向上しました。
関連リンク
- このコミットのGo Gerritへのリンク: https://golang.org/cl/5599048
- 関連するCL 5576057 (doc: add AllMethods flag to New): https://go-review.googlesource.com/c/go/+/5576057
参考にした情報源リンク
- Go言語の公式ドキュメンテーション (
godoc
コマンドのヘルプやgo/doc
パッケージのドキュメンテーション) - Go言語の匿名フィールドとメソッドの埋め込みに関する解説記事
- Go言語のエクスポートルールに関する解説記事
- Go言語の変更リスト (Change List, CL) のレビューシステム (Gerrit) の利用方法
- GitHubのコミット履歴と差分表示機能