Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 17179] ファイルの概要

このコミットは、Go言語のドキュメンテーションツールがパッケージの概要(synopsis)を解析する際の挙動を改善するものです。具体的には、パッケージの概要がコロンと改行(:\n)で終わる場合に、そのコロンまでを概要として正しく認識するように変更が加えられています。これにより、列挙形式の説明が続くようなドキュメンテーションコメントでも、適切に概要が抽出されるようになります。

コミット

commit c272fd14a8bf06a729706894b8a074472e9c1b79
Author: David Symonds <dsymonds@golang.org>
Date:   Tue Aug 13 16:20:17 2013 +1000

    go/doc: permit a package synopsis to end with ":\n".
    
    R=gri, r
    CC=golang-dev
    https://golang.org/cl/12822043

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/c272fd14a8bf06a729706894b8a074472e9c1b79

元コミット内容

go/doc: permit a package synopsis to end with ":\n".

このコミットは、go/docパッケージにおいて、パッケージの概要(synopsis)がコロンと改行(:\n)で終わることを許可する変更です。

変更の背景

Go言語のドキュメンテーションツール(go docコマンドやgodocウェブサーバーなど)は、Goのソースコードからドキュメンテーションコメントを抽出し、整形して表示します。この際、パッケージや関数、型などの概要(synopsis)は、コメントの最初の「文」として認識されることが一般的です。

従来のgo/docパッケージのfirstSentenceLen関数は、文の終わりを主にピリオド(.)とそれに続くスペースで判断していました。しかし、ドキュメンテーションコメントの中には、「このパッケージは以下の機能を提供します:\n - 機能A\n - 機能B」のように、コロンと改行で概要を締めくくり、その後に詳細なリストが続く形式で書かれるものがありました。

このようなコメントの場合、従来のfirstSentenceLen関数では、コロンと改行の後に続く詳細なリストまでを誤って概要の一部として認識してしまう可能性がありました。これは、ドキュメンテーションの表示が意図しないものになる原因となります。このコミットは、この問題を解決し、より自然なドキュメンテーションコメントの記述を可能にするために導入されました。

前提知識の解説

Go言語のドキュメンテーション

Go言語では、コードのドキュメンテーションはソースコード内のコメントとして記述されます。go docコマンドやgodocツールは、これらのコメントを解析し、開発者やユーザーがGoのパッケージやAPIを理解するためのドキュメントを生成します。

  • パッケージコメント: パッケージ宣言の直前に記述されるコメントは、そのパッケージ全体の概要を説明します。
  • 概要 (Synopsis): go docgodocがパッケージや関数などのリストを表示する際に使用する、短い説明文です。通常、コメントの最初の文が概要として抽出されます。

go/docパッケージ

go/docパッケージは、Goのソースコードからドキュメンテーションコメントを解析し、構造化されたドキュメントデータ(doc.Packagedoc.Funcなど)を生成するための標準ライブラリです。go docコマンドやgodocツールはこのパッケージを利用してドキュメントを生成しています。

firstSentenceLen関数

go/docパッケージ内のfirstSentenceLen関数は、与えられた文字列の最初の「文」の長さを計算するユーティリティ関数です。この関数は、ドキュメンテーションコメントから概要を抽出する際に使用されます。従来のロジックでは、文の終わりを検出するために以下のルールが適用されていました。

  • ピリオド(.)の後にスペースが続き、かつそのピリオドの直前が1文字の大文字ではない場合。これは「Mr. Smith」のような略語のピリオドと区別するためです。

このコミットでは、上記のルールに加えて、コロン(:)の後に改行(\n)が続く場合も文の終わりと見なす新しいルールが追加されました。

技術的詳細

このコミットの主要な変更は、src/pkg/go/doc/synopsis.goファイル内のfirstSentenceLen関数にあります。この関数は、入力文字列sをルーン(Unicodeコードポイント)単位で走査し、文の終わりを示すパターンを検出します。

変更前は、文の終わりを検出するロジックは主にピリオド(.)とそれに続くスペースの組み合わせに依存していました。しかし、このコミットでは、コロン(:)の直後に改行(\n)が続くパターンも文の終わりとして認識するように、新たな条件が追加されました。

具体的には、ルーンpがコロン(:)であり、現在のルーンqが改行(\n)である場合に、現在のインデックスiを文の終わりとして返すように変更されています。これにより、例えば「Package foo does these things:\n - a\n - b」のようなコメントがあった場合、「Package foo does these things:」までが概要として正しく抽出されるようになります。

また、src/pkg/go/doc/synopsis_test.goには、この新しい挙動を検証するためのテストケースが追加されています。これにより、変更が意図した通りに機能し、既存の挙動を壊していないことが保証されます。

コアとなるコードの変更箇所

src/pkg/go/doc/synopsis.go

--- a/src/pkg/go/doc/synopsis.go
+++ b/src/pkg/go/doc/synopsis.go
@@ -10,12 +10,15 @@ import (
 )
 
 // firstSentenceLen returns the length of the first sentence in s.
-// The sentence ends after the first period followed by space and
-// not preceded by exactly one uppercase letter.
-//
+// The sentence ends at the first colon followed by a newline,
+// or at the first period followed by space and not preceded by
+// exactly one uppercase letter.
 func firstSentenceLen(s string) int {
  	var ppp, pp, p rune
  	for i, q := range s {
+\t\tif p == ':' && q == '\n' {
+\t\t\treturn i
+\t\t}
  		if q == '\n' || q == '\r' || q == '\t' {
  			q = ' '
  		}

src/pkg/go/doc/synopsis_test.go

--- a/src/pkg/go/doc/synopsis_test.go
+++ b/src/pkg/go/doc/synopsis_test.go
@@ -29,6 +29,7 @@ var tests = []struct {
  	{"Package Καλημέρα κόσμε.", 36, "Package Καλημέρα κόσμε."},
  	{"Package こんにちは 世界\n", 31, "Package こんにちは 世界"},
  	{"Package foo does bar.", 21, "Package foo does bar."},
+\t{"Package foo does these things:\n  - a\n  - b", 30, "Package foo does these things:"},\
  	{"Copyright 2012 Google, Inc. Package foo does bar.", 27, ""},\
  	{"All Rights reserved. Package foo does bar.", 20, ""},\
  	{"All rights reserved. Package foo does bar.", 20, ""},\

コアとなるコードの解説

src/pkg/go/doc/synopsis.go の変更

firstSentenceLen関数は、文字列sをルーンごとに反復処理します。 追加されたコードブロック:

		if p == ':' && q == '\n' {
			return i
		}

このコードは、現在のルーンqが改行文字(\n)であり、かつ直前のルーンpがコロン(:)である場合に真となります。この条件が満たされた場合、関数は現在のインデックスiを返します。これは、コロンと改行の組み合わせが文の終わりとして認識されたことを意味し、その位置までの文字列が概要として扱われます。

この変更により、ドキュメンテーションコメントが「:」で終わり、その直後に改行が続く場合(例えば、箇条書きの導入など)、その「:」までが適切に概要として抽出されるようになります。

src/pkg/go/doc/synopsis_test.go の変更

追加されたテストケース:

	{"Package foo does these things:\n  - a\n  - b", 30, "Package foo does these things:"},

このテストケースは、新しい挙動を具体的に検証します。

  • 入力文字列: "Package foo does these things:\n - a\n - b"
  • 期待される長さ: 30 (これは「Package foo does these things:」の長さです)
  • 期待される概要: "Package foo does these things:"

このテストケースが成功することで、firstSentenceLen関数がコロンと改行で終わる文字列を正しく処理し、期待される概要を抽出できることが確認されます。

関連リンク

参考にした情報源リンク

  • Go言語のソースコード(go/docパッケージ)
  • Go言語の公式ドキュメンテーション
  • コミットメッセージと差分
  • Go言語のIssueトラッカーやメーリングリスト(関連する議論がある場合)
    • 今回のコミットにはhttps://golang.org/cl/12822043というChange-IDが記載されており、これはGerritのコードレビューシステムへのリンクです。このリンクを辿ることで、コミットに至るまでの議論や背景をさらに深く理解できます。
      • https://golang.org/cl/12822043 (現在はgo.googlesource.comにリダイレクトされます)
      • このChange-IDから、元のIssueや関連する議論を検索することも可能です。