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

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

このコミットは、Goプロジェクトのコードレビューツールである codereview.pyCheckTabfmt 関数における変更を記録しています。具体的には、y.tab.[ch] という命名規則を持つファイル(通常、Yacc/Bisonなどのパーサジェネレータによって生成されるファイル)が、タブによるインデントのチェックから除外されるように修正されました。これにより、生成されたコードがGoのコーディング規約に厳密に従わない場合でも、不必要な警告やエラーが発生するのを防ぎます。

コミット

commit 870c9d1c096c44eaad5fd8e9aeeae8b6255fc4d2
Author: Russ Cox <rsc@golang.org>
Date:   Fri Feb 3 10:54:05 2012 -0500

    codereview: allow spaces in y.tab.[ch]
    
    R=golang-dev, bradfitz
    CC=golang-dev
    https://golang.org/cl/5620053

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

https://github.com/golang/go/commit/870c9d1c096c44eaad5fd8e9aeeae8b6255fc4d2

元コミット内容

元のコミットメッセージは「codereview: allow spaces in y.tab.[ch]」と簡潔に述べられています。これは、codereview ツールが y.tab.cy.tab.h といったファイルにおいて、スペースの使用を許可するように変更されたことを意味しています。Goのコーディング規約ではタブによるインデントが推奨されていますが、これらのファイルは通常、自動生成されるものであり、その生成プロセスによってはスペースが使用されることがあります。この変更は、そうした自動生成ファイルに対する柔軟性を持たせるためのものです。

変更の背景

Goプロジェクトでは、コードの品質と一貫性を保つために、厳格なコーディング規約と自動化されたコードレビュープロセスが導入されています。その一環として、codereview.py スクリプトが使用され、Goのソースコードが特定のフォーマット(例: タブによるインデント)に従っているかをチェックします。

しかし、y.tab.[ch] のようなファイルは、Yacc(Yet Another Compiler Compiler)やBisonといったパーサジェネレータによって自動生成されるC言語のソースファイルやヘッダファイルです。これらのツールは、文法定義ファイル(通常 .y 拡張子を持つ)から、構文解析器(パーサ)のC言語コードを生成します。生成されるコードのインデントスタイルは、Goの標準的なタブインデントの規約と異なる場合があり、特にスペースが使用されることがあります。

このコミットが行われる前は、codereview.pyCheckTabfmt 関数が、これらの自動生成された y.tab.[ch] ファイルに対してもタブインデントのチェックを適用していました。その結果、Goのプロジェクト内で使用されているパーサジェネレータが生成するコードがスペースインデントを含んでいた場合、コードレビュープロセスで不必要な警告やエラーが発生し、開発者の手間を増やしていました。

この変更の背景には、自動生成されたファイルに対しては、手書きのコードと同じ厳格なフォーマット規約を適用することが非現実的である、という認識があります。自動生成ファイルは開発者が直接編集するものではなく、そのフォーマットは生成ツールの設定に依存するため、Goの規約に合わせることは困難です。したがって、これらのファイルをチェックの対象から除外することで、コードレビュープロセスの効率化と、開発者の負担軽減を図ることが目的でした。

前提知識の解説

codereview.py

codereview.py は、Goプロジェクトでコードレビューを行う際に使用されるPythonスクリプトです。このスクリプトは、コミットされるコードがGoのコーディング規約やスタイルガイドラインに準拠しているかを自動的にチェックする様々な関数を含んでいます。例えば、gofmt によるフォーマットチェックや、タブによるインデントのチェック(CheckTabfmt)などがあります。これは、コードの一貫性を保ち、可読性を向上させるために重要なツールです。

y.tab.[ch] ファイル

y.tab.c および y.tab.h は、主にUnix系のシステムで広く使われているパーサジェネレータであるYacc(またはそのGNU版であるBison)によって生成されるファイルの名前の慣例です。

  • Yacc/Bison: これらは、形式文法(通常、BNF記法に似た形式で記述される)を読み込み、その文法を解析するためのC言語のコード(構文解析器)を生成するツールです。コンパイラやインタプリタのフロントエンド部分を開発する際によく利用されます。
  • y.tab.c: Yacc/Bisonが生成するC言語のソースファイルで、実際の構文解析ロジック(パーサの有限オートマトンやアクションコードなど)が含まれています。
  • y.tab.h: Yacc/Bisonが生成するC言語のヘッダファイルで、トークン定義やパーサの状態に関する情報などが含まれています。

これらのファイルは、開発者が手動で記述するものではなく、文法定義ファイル(例: parser.y)から自動的に生成されます。そのため、生成されるコードのインデントスタイルやその他のフォーマットは、Yacc/Bisonの設定やバージョンに依存し、必ずしもGoのコーディング規約(特にタブインデントの強制)に合致するとは限りません。

タブインデントのチェック

Go言語の公式なコーディングスタイルでは、インデントにタブを使用することが強く推奨されています。これは、コードの可読性を高め、異なる開発環境間での表示の一貫性を保つためです。codereview.pyCheckTabfmt 関数は、この規約が守られているかを検証する役割を担っています。この関数は、指定されたファイルの内容を読み込み、スペースによるインデントがないか、あるいはタブ以外の文字がインデントに使用されていないかを正規表現などを用いてチェックします。

技術的詳細

このコミットの技術的な変更は、lib/codereview/codereview.py ファイル内の CheckTabfmt 関数における正規表現の修正に集約されます。

変更前のコードは以下の通りでした。

files = [f for f in files if f.startswith('src/') and re.search(r"\.[chys]$", f)]

この行は、CheckTabfmt 関数が処理するファイルのリストをフィルタリングしています。具体的には、ファイルパスが src/ で始まり、かつファイル名が .c.h.y、または .s で終わるファイル(C言語のソースファイル、ヘッダファイル、Yaccの文法定義ファイル、アセンブリファイル)を対象としていました。

変更後のコードは以下の通りです。

files = [f for f in files if f.startswith('src/') and re.search(r"\.[chys]$", f) and not re.search(r"\.tab\.[ch]$", f)]

この変更では、既存の条件に加えて、新たな条件 and not re.search(r"\.tab\.[ch]$", f) が追加されています。

  • re.search(r"\.tab\.[ch]$", f): この正規表現は、ファイル名が .tab.c または .tab.h で終わるかどうかをチェックします。
    • \.: ドット文字そのものにマッチさせるためにエスケープしています。
    • tab: 文字列 "tab" にマッチします。
    • \.: 再びドット文字にマッチさせます。
    • [ch]: 文字 "c" または "h" のいずれかにマッチします。
    • $: 文字列の末尾にマッチします。
  • not: このキーワードにより、正規表現にマッチしないファイル(つまり、y.tab.cy.tab.h ではないファイル)のみがフィルタリング後のリストに含まれるようになります。

したがって、この変更により、CheckTabfmt 関数は、src/ ディレクトリ内の .c, .h, .y, .s ファイルのうち、ファイル名が y.tab.c または y.tab.h で終わらないものだけを対象とするようになりました。これにより、Yacc/Bisonによって生成される y.tab.[ch] ファイルは、タブインデントのチェックから明示的に除外されることになります。

この修正は、Goのコードベースにおける自動生成ファイルの特殊性を考慮し、コードレビュープロセスの精度と実用性を向上させるためのものです。

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

--- a/lib/codereview/codereview.py
+++ b/lib/codereview/codereview.py
@@ -925,7 +925,7 @@ def CheckGofmt(ui, repo, files, just_warn):\
 
 # Check that *.[chys] files indent using tabs.
 def CheckTabfmt(ui, repo, files, just_warn):\
-\tfiles = [f for f in files if f.startswith('src/') and re.search(r"\.[chys]$", f)]\
+\tfiles = [f for f in files if f.startswith('src/') and re.search(r"\.[chys]$", f) and not re.search(r"\.tab\.[ch]$", f)]\
 \tif not files:\
 \t\treturn\
 \tcwd = os.getcwd()\

コアとなるコードの解説

変更された行は、CheckTabfmt 関数内で、タブインデントのチェック対象となるファイルを絞り込むためのリスト内包表記です。

元のコード: files = [f for f in files if f.startswith('src/') and re.search(r"\.[chys]$", f)]

この行は、files リストから以下の条件を満たすファイルを選び出していました。

  1. ファイルパスが 'src/' で始まる。
  2. ファイル名が .c, .h, .y, .s のいずれかで終わる。

変更後のコード: files = [f for f in files if f.startswith('src/') and re.search(r"\.[chys]$", f) and not re.search(r"\.tab\.[ch]$", f)]

この変更では、上記の2つの条件に加えて、さらに以下の条件が追加されました。 3. ファイル名が .tab.c または .tab.h で終わらない。

この追加された条件 and not re.search(r"\.tab\.[ch]$", f) が、y.tab.cy.tab.h といった自動生成ファイルをタブインデントのチェック対象から除外する役割を果たしています。これにより、パーサジェネレータによって生成されたファイルがGoのコーディング規約に合致しないインデントスタイルを持っていても、コードレビュープロセスでエラーとしてフラグされることがなくなりました。これは、自動生成コードの特性を考慮した実用的な改善と言えます。

関連リンク

参考にした情報源リンク