[インデックス 10311] ファイルの概要
このコミットは、以前のコミット ea8b178f9b73
(CL 5375043) で導入された GOEXPERIMENT=reorg
という実験的な機能を元に戻すものです。具体的には、Goコンパイラ (gc
) 内のコードから、reorg
というフラグと、それに関連するパッケージパスのリライトロジック (reorgpath
関数と reorgtab
テーブル) を削除しています。
コミット
commit 1eadb89ee1d235d2e716cc7474976676db5f8bd4
Author: Russ Cox <rsc@golang.org>
Date: Wed Nov 9 12:36:51 2011 -0500
undo CL 5375043 / ea8b178f9b73
Never lasts long.
««« original CL description
gc: add GOEXPERIMENT=reorg
This won't last long but may ease conversions.
R=ken2
CC=golang-dev
https://golang.org/cl/5375043
»»»
R=ken2, ken
CC=golang-dev
https://golang.org/cl/5370043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/1eadb89ee1d235d2e716cc7474976676db5f8bd4
元コミット内容
このコミットが元に戻している元のコミット (ea8b178f9b73
/ CL 5375043) の内容は以下の通りです。
gc: add GOEXPERIMENT=reorg
This won't last long but may ease conversions.
これは、Goコンパイラ (gc
) に GOEXPERIMENT=reorg
という実験的なフラグを追加するものでした。このフラグは、パッケージのインポートパスの変換を容易にすることを目的としていましたが、一時的なものとして導入されたことが示唆されています。
変更の背景
このコミットの背景には、Go言語の標準ライブラリのパッケージ構造の再編成("reorganization")がありました。Go言語の初期段階では、一部のパッケージがより一般的なカテゴリの下に移動されるなど、パスが変更されることがありました。例えば、json
パッケージが encoding/json
に、http
パッケージが net/http
に移動するといった変更です。
このような大規模なパッケージパスの変更は、既存のコードベースに大きな影響を与えます。開発者は、新しいパッケージパスに合わせてコードを修正する必要がありました。GOEXPERIMENT=reorg
は、この移行期間中の開発者の負担を軽減するために導入された一時的なメカニズムでした。このフラグを有効にすると、コンパイラが古いパッケージパスを新しいパスに自動的にマッピングすることで、コードの修正なしにコンパイルを可能にしようとしました。
しかし、コミットメッセージにある「Never lasts long. (長くは続かない)」という言葉が示すように、このような自動変換は一時的な回避策であり、最終的には開発者がコードを新しいパスに更新することが期待されていました。このコミットは、その一時的な期間が終了し、GOEXPERIMENT=reorg
の機能が不要になったため、関連するコードを削除するものです。これは、Go言語の進化と、パッケージ構造の安定化に向けたステップと見なすことができます。
前提知識の解説
Go言語のコンパイラ (gc
)
Go言語の公式コンパイラは、通常 gc
と呼ばれます。これは、Goソースコードを機械語に変換する役割を担っています。Goのツールチェインの一部として提供され、go build
コマンドなどで内部的に利用されます。
GOEXPERIMENT
環境変数
GOEXPERIMENT
は、Go言語のツールチェイン(コンパイラ、リンカなど)の実験的な機能を有効にするために使用される環境変数です。Goの開発チームは、新しい機能や大きな変更を導入する前に、この環境変数を使ってそれらをテストし、フィードバックを収集することがあります。GOEXPERIMENT
で有効にされた機能は、安定版のGoリリースには含まれない可能性があり、将来的に変更されたり削除されたりすることがあります。このコミットのケースのように、一時的な互換性レイヤーを提供するためにも使用されることがあります。
パッケージのインポートパス
Go言語では、他のパッケージの機能を利用するために import
ステートメントを使用します。import "path/to/package"
のように、パッケージのインポートパスを指定します。このパスは、Goのワークスペース内のパッケージの場所や、Goモジュールにおけるパッケージの識別子に対応します。Goの標準ライブラリのパッケージも、fmt
や net/http
のように特定のインポートパスを持っています。
Strlit
構造体
Goコンパイラの内部で使用される文字列リテラルを表す構造体です。コンパイラがソースコードを解析する際に、文字列定数や識別子などをこの形式で扱います。
技術的詳細
このコミットは、Goコンパイラ (src/cmd/gc/go.h
と src/cmd/gc/lex.c
) から GOEXPERIMENT=reorg
に関連するコードを削除しています。
具体的には、以下の要素が削除されています。
reorg
グローバル変数:src/cmd/gc/go.h
からEXTERN int reorg;
の宣言が削除されています。これは、GOEXPERIMENT=reorg
が有効かどうかを判断するためのフラグでした。exper
配列からのreorg
エントリの削除:src/cmd/gc/lex.c
内のexper
配列は、GOEXPERIMENT
環境変数で制御される実験的なフラグを定義しています。ここから{"reorg", &reorg},
のエントリが削除され、GOEXPERIMENT=reorg
を介してreorg
フラグを制御するメカニズムがなくなりました。reorgpath
関数の削除:src/cmd/gc/lex.c
からreorgpath
関数とそのプロトタイプ宣言が削除されています。この関数は、古いパッケージパスを新しいパッケージパスに変換するロジックをカプセル化していました。importfile
関数内のreorg
関連ロジックの削除:src/cmd/gc/lex.c
のimportfile
関数は、Goソースコード内のimport
ステートメントを処理する部分です。以前は、reorg
フラグが有効な場合にreorgpath
関数を呼び出してインポートパスを変換していましたが、この条件分岐と関数呼び出しが削除されました。reorgtab
テーブルの削除:src/cmd/gc/lex.c
からreorgtab
という静的な構造体配列が削除されています。このテーブルは、古いパッケージパスと新しいパッケージパスのマッピングを定義していました。例えば、{"json", "encoding/json"}
のようなエントリが含まれていました。
これらの変更により、Goコンパイラは GOEXPERIMENT=reorg
の機能を持たなくなり、インポートパスの自動変換は行われなくなります。これは、Go言語の標準ライブラリのパッケージ構造が安定し、開発者が手動でインポートパスを更新することが期待されるようになったことを意味します。
コアとなるコードの変更箇所
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h
index 266cc8597d..faae7bd9ea 100644
--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -852,7 +852,6 @@ EXTERN int typecheckok;
EXTERN int compiling_runtime;
EXTERN int rune32;
-EXTERN int reorg;
/*
* y.tab.c
diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c
index a07232d1bd..b1eab441c3 100644
--- a/src/cmd/gc/lex.c
+++ b/src/cmd/gc/lex.c
@@ -18,8 +18,6 @@ int windows;
int yyprev;
int yylast;
-Strlit *reorgpath(Strlit*);
-
static void lexinit(void);
static void lexinit1(void);
static void lexfini(void);
@@ -40,7 +38,6 @@ static struct {
int *val;
} exper[] = {
{"rune32", &rune32},
- {"reorg", &reorg},
};
static void
@@ -540,9 +537,6 @@ importfile(Val *f, int line)
yyerror("import path contains NUL");
errorexit();
}
-
- if(reorg)
- f->u.sval = reorgpath(f->u.sval);
// The package name main is no longer reserved,
// but we reserve the import path "main" to identify
@@ -2121,47 +2115,3 @@ mkpackage(char* pkgname)
outfile = smprint("%s.%c", namebuf, thechar);
}
}
-
-static struct {
- char *old;
- char *xnew;
-} reorgtab[] = {
- {"asn1", "encoding/asn1"},
- {"big", "math/big"},
- {"cmath", "math/cmplx"},
- {"csv", "encoding/csv"},
- {"exec", "os/exec"},
- {"exp/template/html", "html/template"},
- {"gob", "encoding/gob"},
- {"http", "net/http"},
- {"http/cgi", "net/http/cgi"},
- {"http/fcgi", "net/http/fcgi"},
- {"http/httptest", "net/http/httptest"},
- {"http/pprof", "net/http/pprof"},
- {"json", "encoding/json"},
- {"mail", "net/mail"},
- {"rpc", "net/rpc"},
- {"rpc/jsonrpc", "net/rpc/jsonrpc"},
- {"scanner", "text/scanner"},
- {"smtp", "net/smtp"},
- {"syslog", "log/syslog"},
- {"tabwriter", "text/tabwriter"},
- {"template", "text/template"},
- {"template/parse", "text/template/parse"},
- {"rand", "math/rand"},
- {"url", "net/url"},
- {"utf16", "unicode/utf16"},
- {"utf8", "unicode/utf8"},
- {"xml", "encoding/xml"},
-};
-
-Strlit*
-reorgpath(Strlit *s)
-{
- int i;
-
- for(i=0; i < nelem(reorgtab); i++)
- if(strcmp(s->s, reorgtab[i].old) == 0)
- return strlit(reorgtab[i].xnew);
- return s;
-}
コアとなるコードの解説
src/cmd/gc/go.h
-EXTERN int reorg;
reorg
という名前のグローバル変数の宣言が削除されています。この変数は、GOEXPERIMENT=reorg
が有効であるかどうかを示すフラグとして使用されていました。この行の削除により、コンパイラの他の部分からreorg
フラグを参照する手段がなくなります。
src/cmd/gc/lex.c
-Strlit *reorgpath(Strlit*);
reorgpath
関数の前方宣言が削除されています。これは、この関数自体が削除されるため、不要になったものです。
exper
配列の変更:- {"reorg", &reorg},
exper
配列は、GOEXPERIMENT
環境変数によって制御される実験的なフラグとその対応するグローバル変数をマッピングしています。ここから{"reorg", &reorg}
のエントリが削除されたことで、GOEXPERIMENT=reorg
を設定してもreorg
変数が有効になることはなくなりました。
importfile
関数の変更:- if(reorg) - f->u.sval = reorgpath(f->u.sval);
importfile
関数は、Goソースコード内のimport
パスを処理する部分です。以前は、reorg
フラグが有効な場合にのみ、reorgpath
関数を呼び出してインポートパスを変換していました。この条件分岐とreorgpath
の呼び出しが削除されたことで、インポートパスの自動変換ロジックが完全に削除されました。
reorgtab
テーブルとreorgpath
関数の削除:-static struct { - char *old; - char *xnew; -} reorgtab[] = { - {"asn1", "encoding/asn1"}, - // ... (他のエントリ) -}; - -Strlit* -reorgpath(Strlit *s) -{ - int i; - - for(i=0; i < nelem(reorgtab); i++) - if(strcmp(s->s, reorgtab[i].old) == 0) - return strlit(reorgtab[i].xnew); - return s; -}
reorgtab
は、古いパッケージパス(old
)と新しいパッケージパス(xnew
)の対応関係を定義する静的なテーブルでした。reorgpath
関数は、このreorgtab
を参照して、与えられたStrlit
型のインポートパスs
がreorgtab
内のold
パスと一致する場合、対応するxnew
パスに変換して返す役割を担っていました。- これらのコードブロック全体が削除されたことで、パッケージパスの自動変換機能の実装が完全にコンパイラから取り除かれました。
これらの変更は、GOEXPERIMENT=reorg
が提供していた一時的な互換性レイヤーが不要になったことを明確に示しています。
関連リンク
- 元の変更リスト (CL 5375043): https://golang.org/cl/5375043
- このコミットの変更リスト (CL 5370043): https://golang.org/cl/5370043
参考にした情報源リンク
- Go言語の公式ドキュメント (パッケージのインポートパス、
go build
など): https://go.dev/doc/ - Go言語の実験的な機能に関する情報 (GOEXPERIMENT): https://go.dev/doc/go1.18#goexperiment (これはGo 1.18のドキュメントですが、
GOEXPERIMENT
の概念を理解するのに役立ちます) - Go言語のコンパイラ (
gc
) の内部構造に関する情報 (Goのソースコードリポジトリや関連するブログ記事など) - Go言語のパッケージ再編成に関する議論やアナウンス (Goのメーリングリストやブログなど)