[インデックス 16050] ファイルの概要
このコミットは、Go言語のドキュメンテーションツールであるgodoc
の表示に関する修正です。具体的には、godoc
が生成するHTMLドキュメントにおいて、インデックスエントリが不必要にリンク化されるのを防ぐための変更が行われています。
コミット
commit 79682199ce56c9afa1edac6c61da3c7abb9393b7
Author: Robert Griesemer <gri@golang.org>
Date: Tue Apr 2 12:05:14 2013 -0700
cmd/godoc: don't linkify index entries
Fixes #5186.
R=bradfitz
CC=golang-dev
https://golang.org/cl/8267044
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/79682199ce56c9afa1edac6c61da3c7abb9393b7
元コミット内容
cmd/godoc: don't linkify index entries
Fixes #5186.
このコミットは、godoc
コマンドが生成するドキュメントにおいて、インデックスのエントリがリンク化されないようにするものです。これは、Goの内部的な課題追跡システムにおけるIssue #5186を修正します。
変更の背景
godoc
はGo言語のソースコードからドキュメントを自動生成するツールであり、開発者がGoのパッケージや関数、型などの情報を参照する際に非常に重要な役割を果たします。生成されるドキュメントはHTML形式であり、通常、関数名や型名などはその定義箇所へのリンクとして表示されます。
しかし、このコミットの背景には、godoc
が生成するパッケージのインデックス(目次のようなもの)において、本来リンクである必要のない箇所までリンク化されてしまうという問題がありました。特に、インデックス内のエントリが、その宣言全体をリンクとして表示してしまうと、視覚的に煩雑になるだけでなく、ユーザーエクスペリエンスを損なう可能性がありました。
この問題は、godoc
のHTMLテンプレートと、コードをHTMLに変換するロジックの連携に起因していました。特定の要素(例えば、関数の宣言全体)が、その要素自体がリンクであるべきではない文脈(インデックスなど)でも、デフォルトでリンクとして処理されてしまっていたと考えられます。
前提知識の解説
godoc
: Go言語のソースコードからドキュメントを生成し、HTTPサーバーとして提供するツールです。Goの標準ライブラリのドキュメントもgodoc
によって生成されています。- HTMLテンプレート:
godoc
はGoのhtml/template
パッケージを使用してHTMLドキュメントを生成します。テンプレートファイル(例:package.html
)は、Goのコードから取得したデータ(パッケージ情報、関数、型など)を埋め込んで最終的なHTMLを構築します。 ast.Node
: Goのgo/ast
パッケージで定義されている抽象構文木(AST)のノードを表すインターフェースです。Goのソースコードは、パースされるとASTとして表現され、godoc
はこのASTを走査してドキュメント情報を抽出します。- リンク化 (Linkify): テキスト内の特定の要素(例: 関数名、型名)を、その定義箇所や関連情報へのハイパーリンクに変換する処理を指します。
godoc
では、ソースコード内の識別子を、その識別子の宣言箇所へのリンクとして表示する機能があります。 node_htmlFunc
:godoc
の内部で、ASTノードをHTML形式に変換する際に使用される関数です。この関数は、Goのコード要素(関数宣言、変数宣言など)を整形してHTML文字列として出力する役割を担っています。
技術的詳細
このコミットの主要な変更点は、godoc
のHTML生成ロジックにおいて、ASTノードをHTMLに変換するnode_htmlFunc
関数に新しい引数linkify
(ブール値)が追加されたことです。
変更前は、node_htmlFunc
はASTノードを受け取り、そのノードをHTMLとして整形する際に、常にリンク化の可能性を考慮していました。特に、declLinks
というフラグが有効な場合、識別子をその宣言へのリンクとして変換しようと試みていました。
変更後は、node_htmlFunc
のシグネチャが以下のように変更されました。
func node_htmlFunc(info *PageInfo, node interface{}, linkify bool) string
このlinkify
引数は、そのASTノードをHTMLに変換する際に、識別子をリンク化するかどうかを明示的に制御します。
linkify
がtrue
の場合: 以前と同様に、declLinks
フラグが有効であれば、識別子はリンク化されます。linkify
がfalse
の場合: 識別子はリンク化されず、単なるテキストとして整形されます。
この変更により、lib/godoc/package.html
テンプレート内でnode_htmlFunc
を呼び出す際に、文脈に応じてlinkify
引数をtrue
またはfalse
で渡すことができるようになりました。
具体的には、パッケージのインデックス部分(関数、型、定数、変数などの一覧)では、宣言全体をリンク化する必要がないため、linkify
にfalse
が渡されるようになりました。これにより、インデックスエントリは整形されたテキストとして表示され、不必要なリンクが生成されなくなりました。
一方で、実際の宣言箇所(例: 関数の詳細セクション)では、引き続き識別子をリンク化する必要があるため、linkify
にtrue
が渡されています。
コアとなるコードの変更箇所
lib/godoc/package.html
このファイルは、godoc
がパッケージのドキュメントを生成する際に使用するHTMLテンプレートです。
変更点としては、node_html
テンプレート関数が呼び出されている箇所で、第2引数にfalse
またはtrue
が追加されています。
--- a/lib/godoc/package.html
+++ b/lib/godoc/package.html
@@ -60,18 +60,18 @@
{{end}}
{{range .Funcs}}
{{$name_html := html .Name}}
- <dd><a href="#{{$name_html}}">{{node_html $ .Decl}}</a></dd>
+ <dd><a href="#{{$name_html}}">{{node_html $ .Decl false}}</a></dd>
{{end}}
{{range .Types}}
{{$tname_html := html .Name}}
<dd><a href="#{{$tname_html}}">type {{$tname_html}}</a></dd>
{{range .Funcs}}
{{$name_html := html .Name}}
- <dd> <a href="#{{$name_html}}">{{node_html $ .Decl}}</a></dd>
+ <dd> <a href="#{{$name_html}}">{{node_html $ .Decl false}}</a></dd>
{{end}}
{{range .Methods}}
{{$name_html := html .Name}}
- <dd> <a href="#{{$tname_html}}.{{$name_html}}">{{node_html $ .Decl}}</a></dd>
+ <dd> <a href="#{{$tname_html}}.{{$name_html}}">{{node_html $ .Decl false}}</a></dd>
{{end}}
{{end}}
{{if $.Notes}}
@@ -109,14 +109,14 @@
{{with .Consts}}
<h2 id="pkg-constants">Constants</h2>
{{range .}}
- <pre>{{node_html $ .Decl}}</pre>
+ <pre>{{node_html $ .Decl true}}</pre>
{{comment_html .Doc}}\n
{{end}}
{{end}}
{{with .Vars}}
<h2 id="pkg-variables">Variables</h2>
{{range .}}
- <pre>{{node_html $ .Decl}}</pre>
+ <pre>{{node_html $ .Decl true}}</pre>
{{comment_html .Doc}}\n
{{end}}
{{end}}
@@ -124,7 +124,7 @@
{{/* Name is a string - no need for FSet */}}
{{$name_html := html .Name}}
<h2 id="{{$name_html}}">func <a href="{{posLink_url $ .Decl}}">{{$name_html}}</a></h2>
- <pre>{{node_html $ .Decl}}</pre>
+ <pre>{{node_html $ .Decl true}}</pre>
{{comment_html .Doc}}\n
{{example_html $ .Name}}\n
{{end}}
@@ -132,16 +132,16 @@
{{$tname := .Name}}
{{$tname_html := html .Name}}\n
<h2 id="{{$tname_html}}">type <a href="{{posLink_url $ .Decl}}">{{$tname_html}}</a></h2>
- <pre>{{node_html $ .Decl}}</pre>
+ <pre>{{node_html $ .Decl true}}</pre>
{{comment_html .Doc}}\n
{{range .Consts}}
- <pre>{{node_html $ .Decl}}</pre>
+ <pre>{{node_html $ .Decl true}}</pre>
{{comment_html .Doc}}\n
{{end}}
{{range .Vars}}
- <pre>{{node_html $ .Decl}}</pre>
+ <pre>{{node_html $ .Decl true}}</pre>
{{comment_html .Doc}}\n
{{end}}
@@ -150,7 +150,7 @@
{{range .Funcs}}
{{$name_html := html .Name}}
<h3 id="{{$name_html}}">func <a href="{{posLink_url $ .Decl}}">{{$name_html}}</a></h3>
- <pre>{{node_html $ .Decl}}</pre>
+ <pre>{{node_html $ .Decl true}}</pre>
{{comment_html .Doc}}\n
{{example_html $ .Name}}\n
{{end}}
@@ -158,7 +158,7 @@
{{range .Methods}}
{{$name_html := html .Name}}
<h3 id="{{$tname_html}}.{{$name_html}}">func ({{html .Recv}}) <a href="{{posLink_url $ .Decl}}">{{$name_html}}</a></h3>
- <pre>{{node_html $ .Decl}}</pre>
+ <pre>{{node_html $ .Decl true}}</pre>
{{comment_html .Doc}}\n
{{$name := printf "%s_%s" $tname .Name}}\n
{{example_html $ $name}}\n
@@ -179,7 +179,7 @@
{{end}}\n
{{with .PAst}}
-\t<pre>{{node_html $ .}}</pre>
+\t<pre>{{node_html $ . false}}</pre>
{{end}}\n
{{with .Dirs}}
src/cmd/godoc/godoc.go
このファイルはgodoc
コマンドの主要なロジックを含んでいます。
node_htmlFunc
関数のシグネチャが変更され、linkify
引数が追加されました。また、その引数に基づいてリンク化の処理を条件分岐するようになりました。
--- a/src/cmd/godoc/godoc.go
+++ b/src/cmd/godoc/godoc.go
@@ -279,14 +279,12 @@ func nodeFunc(info *PageInfo, node interface{}) string {
return buf.String()
}
-func node_htmlFunc(info *PageInfo, node interface{}) string {
+func node_htmlFunc(info *PageInfo, node interface{}, linkify bool) string {
var buf1 bytes.Buffer
writeNode(&buf1, info.FSet, node)
var buf2 bytes.Buffer
- // Don't linkify full source text (info.PAst != nil) - identifier
- // resolution is not strong enough without full type checking.
- if n, _ := node.(ast.Node); n != nil && *declLinks && info.PAst == nil {
+ if n, _ := node.(ast.Node); n != nil && linkify && *declLinks {
LinkifyText(&buf2, buf1.Bytes(), n)
} else {
FormatText(&buf2, buf1.Bytes(), -1, true, "", nil)
@@ -394,7 +392,7 @@ func example_htmlFunc(info *PageInfo, funcName string) string {
// print code
cnode := &printer.CommentedNode{Node: eg.Code, Comments: eg.Comments}
- code := node_htmlFunc(info, cnode)
+ code := node_htmlFunc(info, cnode, true)
out := eg.Output
wholeFile := true
コアとなるコードの解説
src/cmd/godoc/godoc.go
内のnode_htmlFunc
関数は、GoのASTノードをHTML形式の文字列に変換する役割を担っています。この関数は、Goのコード要素(関数宣言、変数宣言、型宣言など)を整形し、必要に応じて識別子をリンク化します。
変更前は、この関数はinfo *PageInfo
とnode interface{}
の2つの引数を受け取っていました。info.PAst == nil
という条件で、完全なソーステキストではない場合にリンク化を行うというロジックが含まれていましたが、これがインデックスエントリの不必要なリンク化を引き起こしていました。
変更後は、linkify bool
という新しい引数が追加されました。この引数は、呼び出し元が明示的にリンク化を許可するかどうかを制御します。
if n, _ := node.(ast.Node); n != nil && linkify && *declLinks {
LinkifyText(&buf2, buf1.Bytes(), n)
} else {
FormatText(&buf2, buf1.Bytes(), -1, true, "", nil)
}
このif
文が、リンク化の有無を決定する主要なロジックです。
n != nil
: 変換対象が有効なASTノードであること。linkify
: 新しく追加された引数で、呼び出し元がリンク化を許可していること。*declLinks
: グローバルな設定で、宣言へのリンクが有効になっていること。
これらの条件がすべて満たされた場合にのみ、LinkifyText
関数が呼び出され、ASTノード内の識別子が対応する宣言へのリンクとして変換されます。それ以外の場合は、FormatText
関数が呼び出され、単なる整形されたテキストとして出力されます。
lib/godoc/package.html
テンプレートでは、このnode_htmlFunc
の変更に合わせて、各箇所でlinkify
引数が適切に渡されるようになりました。
- パッケージのインデックス部分(
Funcs
,Types
,Methods
などのdd
タグ内)では、node_html $ .Decl false
のようにfalse
が渡され、リンク化が抑制されます。これにより、インデックスは簡潔なテキスト表示になります。 - 定数、変数、関数、型の詳細な宣言部分(
h2
,h3
タグの後のpre
タグ内)では、node_html $ .Decl true
のようにtrue
が渡され、識別子が引き続きリンク化されます。これは、これらの箇所では詳細な情報へのナビゲーションが期待されるためです。
この修正により、godoc
の出力はより洗練され、ユーザーがドキュメントを閲覧する際の視覚的なノイズが減少し、必要な情報へのアクセスが改善されました。
関連リンク
- Go言語公式ドキュメント: https://go.dev/
godoc
コマンドのドキュメント: https://pkg.go.dev/cmd/godoc
参考にした情報源リンク
- Go言語のソースコード (GitHub): https://github.com/golang/go
- Go言語のIssueトラッカー (GitHub): https://github.com/golang/go/issues
- Go言語のコードレビューシステム (Gerrit): https://go-review.googlesource.com/ (コミットメッセージにある
https://golang.org/cl/8267044
はこのGerritの変更リストへのリンクです) html/template
パッケージのドキュメント: https://pkg.go.dev/html/templatego/ast
パッケージのドキュメント: https://pkg.go.dev/go/ast