[インデックス 12607] ファイルの概要
このコミットは、Go言語のコンパイラ(gc
)において、インポートパスにチルダ(~
)文字の使用を許可するように変更を加えるものです。これにより、Windows環境における特定のパス形式や、Goパーサーの既存の挙動との整合性が改善され、ビルドの問題が修正されます。
コミット
commit d0a4c9bb626df78230613162b0dc07c72855b3c1
Author: Rob Pike <r@golang.org>
Date: Tue Mar 13 16:03:19 2012 +1100
gc: allow ~ in import paths
Windows has paths like C:/Users/ADMIN~1. Also, it so happens
that go/parser allows ~ in import paths. So does the spec.
Fixes the build too.
R=golang-dev, dsymonds
CC=golang-dev
https://golang.org/cl/5777073
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/d0a4c9bb626df78230613162b0dc07c72855b3c1
元コミット内容
gc: allow ~ in import paths
Windows has paths like C:/Users/ADMIN~1. Also, it so happens
that go/parser allows ~ in import paths. So does the spec.
Fixes the build too.
変更の背景
この変更の背景には、主に以下の2つの要因があります。
- Windowsにおけるパスの特殊性: Windowsオペレーティングシステムでは、ファイルシステムが短いファイル名(8.3形式)をサポートしており、長いファイル名が切り詰められる際にチルダ(
~
)と数字が組み合わされた形式(例:ADMIN~1
)が生成されることがあります。GoのインポートパスがこのようなWindows特有のパスを含む場合、コンパイラがこれを不正な文字として扱ってしまうと、ビルドエラーが発生する可能性がありました。 - Go言語の仕様とパーサーの挙動との不一致: Go言語の仕様(Go Language Specification)では、インポートパスに使用できる文字について特定のルールが定められています。また、
go/parser
パッケージはGoのソースコードを解析する際に、インポートパスにチルダ文字が含まれていても許容する挙動を示していました。しかし、コンパイラ(gc
)の内部処理では、チルダ文字が不正な文字として扱われており、この間に不一致が生じていました。この不一致が、Windows環境でのビルド問題を引き起こす一因となっていました。
このコミットは、これらの不一致を解消し、GoコンパイラがWindowsのパス形式やGo言語の仕様、そしてgo/parser
の挙動と整合性を持つようにすることで、Goプログラムのクロスプラットフォーム互換性とビルドの信頼性を向上させることを目的としています。
前提知識の解説
このコミットを理解するためには、以下の前提知識が役立ちます。
- Go言語のインポートパス: Go言語では、パッケージをインポートする際に、そのパッケージのパスを指定します。このパスは通常、Goモジュールのルートからの相対パスや、標準ライブラリのパッケージ名などです。例えば、
import "fmt"
やimport "github.com/user/repo/pkg"
のように記述されます。インポートパスは、Goツールチェーンがソースファイルを特定し、依存関係を解決するために非常に重要です。 - Goコンパイラ (
gc
):gc
はGo言語の公式コンパイラであり、Goのソースコードを機械語に変換する役割を担っています。コンパイルプロセス中には、インポートパスの解析や検証も行われます。 go/parser
パッケージ: Goの標準ライブラリの一部であるgo/parser
パッケージは、Goのソースコードを解析し、抽象構文木(AST)を生成するために使用されます。このパッケージは、Goのツール(goimports
、gofmt
など)やIDE、リンターなどで広く利用されています。- Windowsのファイルパスと8.3形式: Windowsのファイルシステム(特にFAT32やNTFSの一部互換モード)では、長いファイル名に対して短いファイル名(8.3形式、例:
PROGRA~1
forProgram Files
)が自動的に生成されることがあります。これは、古いDOSアプリケーションとの互換性を保つために導入されたもので、パス中にチルダ(~
)と数字が含まれる特徴があります。 utfrune
関数: このコミットで変更されているutfrune
関数は、Goの内部で文字列(UTF-8エンコードされた文字列)の中から特定のルーン(Unicodeコードポイント)を探すために使用される関数です。C言語のstrchr
やwcschr
に似ていますが、UTF-8文字列を適切に扱います。
技術的詳細
このコミットの技術的な核心は、Goコンパイラのインポートパス検証ロジックの変更にあります。具体的には、src/cmd/gc/subr.c
ファイル内のisbadimport
関数が修正されています。
isbadimport
関数は、与えられたインポートパスがGoの規則に違反していないかをチェックする役割を担っています。この関数は、インポートパスに含まれる各文字を走査し、不正な文字が含まれていないかを確認します。
変更前は、この関数内でインポートパスに含めることができない文字のリストにチルダ(~
)が含まれていました。これは、Goのインポートパスが通常、URLのような形式で表現され、特殊文字の使用が制限されるという一般的な慣習に基づいていた可能性があります。
しかし、前述の通り、Windowsのファイルシステムではチルダを含むパスが合法的に存在し、またGo言語の仕様やgo/parser
の挙動がチルダを許容していたため、コンパイラ側でのこの制限は不整合を引き起こしていました。
このコミットでは、isbadimport
関数内の不正文字リストからチルダ(~
)が削除されました。これにより、コンパイラはインポートパスにチルダが含まれていても、それを不正な文字としてフラグ付けしなくなり、Windows環境でのビルド問題が解消されます。
この変更は、Go言語のクロスプラットフォーム互換性を高める上で重要です。特に、WindowsユーザーがGoのソースコードをビルドする際に、ファイルパスの差異によって予期せぬエラーに遭遇するのを防ぎます。また、Go言語の異なるコンポーネント(コンパイラとパーサー)間での挙動の整合性を保つことにも寄与しています。
コアとなるコードの変更箇所
変更はsrc/cmd/gc/subr.c
ファイルの一箇所のみです。
--- a/src/cmd/gc/subr.c
+++ b/src/cmd/gc/subr.c
@@ -3639,7 +3639,7 @@ isbadimport(Strlit *path)
yyerror("import path contains space character: \"%s\"", path->s);
return 1;
}
- if(utfrune("!\"#$%&'()*,:;<=>?[]^`{|}~", r)) {
+ if(utfrune("!\"#$%&'()*,:;<=>?[]^`{|}", r)) {
yyerror("import path contains invalid character '%C': \"%s\"", r, path->s);
return 1;
}
コアとなるコードの解説
上記のコードスニペットは、isbadimport
関数内の特定の条件分岐を示しています。
if(utfrune("!\"#$%&'()*,:;<=>?[]^
{|}~", r)) { ... }` (変更前)if(utfrune("!\"#$%&'()*,:;<=>?[]^
{|}", r)) { ... }` (変更後)
この行は、インポートパスの各ルーン(r
)が、指定された不正文字の集合に含まれているかどうかをチェックしています。utfrune
関数は、第一引数で与えられた文字列(この場合は不正文字の集合を表す文字列リテラル)の中に、第二引数で与えられたルーンr
が存在するかどうかを調べます。存在すれば真を返し、yyerror
関数を呼び出してエラーメッセージを出力し、1
を返して不正なインポートパスであることを示します。
変更前は、不正文字の集合を表す文字列リテラルにチルダ(~
)が含まれていました。これが、インポートパスにチルダが含まれる場合にエラーとなる原因でした。
変更後、この文字列リテラルからチルダ(~
)が削除されています。これにより、utfrune
関数がチルダに対して真を返すことがなくなり、インポートパスにチルダが含まれていてもエラーとして扱われなくなりました。
この修正は非常に局所的ですが、Goコンパイラのインポートパス処理における重要な挙動変更であり、Windows環境での互換性問題を解決する上で不可欠な変更でした。
関連リンク
- Go Language Specification: https://go.dev/ref/spec (特に "Import declarations" のセクション)
- Go
go/parser
package documentation: https://pkg.go.dev/go/parser - Go CL 5777073 (Gerrit Change-Id): https://golang.org/cl/5777073 (これはコミットメッセージに記載されているGerritの変更リストへのリンクです。GoプロジェクトではGitHubにプッシュされる前にGerritでコードレビューが行われます。)
参考にした情報源リンク
- Windows 8.3 filename: https://en.wikipedia.org/wiki/8.3_filename
- Go source code (for context on
src/cmd/gc/subr.c
andutfrune
): https://github.com/golang/go - General understanding of Go compiler and import paths.
[インデックス 12607] ファイルの概要
このコミットは、Go言語のコンパイラ(gc
)において、インポートパスにチルダ(~
)文字の使用を許可するように変更を加えるものです。これにより、Windows環境における特定のパス形式や、Goパーサーの既存の挙動との整合性が改善され、ビルドの問題が修正されます。
コミット
commit d0a4c9bb626df78230613162b0dc07c72855b3c1
Author: Rob Pike <r@golang.org>
Date: Tue Mar 13 16:03:19 2012 +1100
gc: allow ~ in import paths
Windows has paths like C:/Users/ADMIN~1. Also, it so happens
that go/parser allows ~ in import paths. So does the spec.
Fixes the build too.
R=golang-dev, dsymonds
CC=golang-dev
https://golang.org/cl/5777073
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/d0a4c9bb626df78230613162b0dc07c72855b3c1
元コミット内容
gc: allow ~ in import paths
Windows has paths like C:/Users/ADMIN~1. Also, it so happens
that go/parser allows ~ in import paths. So does the spec.
Fixes the build too.
変更の背景
この変更の背景には、主に以下の2つの要因があります。
- Windowsにおけるパスの特殊性: Windowsオペレーティングシステムでは、ファイルシステムが短いファイル名(8.3形式)をサポートしており、長いファイル名が切り詰められる際にチルダ(
~
)と数字が組み合わされた形式(例:ADMIN~1
)が生成されることがあります。GoのインポートパスがこのようなWindows特有のパスを含む場合、コンパイラがこれを不正な文字として扱ってしまうと、ビルドエラーが発生する可能性がありました。 - Go言語の仕様とパーサーの挙動との不一致: Go言語の仕様(Go Language Specification)では、インポートパスに使用できる文字について特定のルールが定められています。また、
go/parser
パッケージはGoのソースコードを解析する際に、インポートパスにチルダ文字が含まれていても許容する挙動を示していました。しかし、コンパイラ(gc
)の内部処理では、チルダ文字が不正な文字として扱われており、この間に不一致が生じていました。この不一致が、Windows環境でのビルド問題を引き起こす一因となっていました。
このコミットは、これらの不一致を解消し、GoコンパイラがWindowsのパス形式やGo言語の仕様、そしてgo/parser
の挙動と整合性を持つようにすることで、Goプログラムのクロスプラットフォーム互換性とビルドの信頼性を向上させることを目的としています。
前提知識の解説
このコミットを理解するためには、以下の前提知識が役立ちます。
- Go言語のインポートパス: Go言語では、パッケージをインポートする際に、そのパッケージのパスを指定します。このパスは通常、Goモジュールのルートからの相対パスや、標準ライブラリのパッケージ名などです。例えば、
import "fmt"
やimport "github.com/user/repo/pkg"
のように記述されます。インポートパスは、Goツールチェーンがソースファイルを特定し、依存関係を解決するために非常に重要です。 - Goコンパイラ (
gc
):gc
はGo言語の公式コンパイラであり、Goのソースコードを機械語に変換する役割を担っています。コンパイルプロセス中には、インポートパスの解析や検証も行われます。 go/parser
パッケージ: Goの標準ライブラリの一部であるgo/parser
パッケージは、Goのソースコードを解析し、抽象構文木(AST)を生成するために使用されます。このパッケージは、Goのツール(goimports
、gofmt
など)やIDE、リンターなどで広く利用されています。- Windowsのファイルパスと8.3形式: Windowsのファイルシステム(特にFAT32やNTFSの一部互換モード)では、長いファイル名に対して短いファイル名(8.3形式、例:
PROGRA~1
forProgram Files
)が自動的に生成されることがあります。これは、古いDOSアプリケーションとの互換性を保つために導入されたもので、パス中にチルダ(~
)と数字が含まれる特徴があります。 utfrune
関数: このコミットで変更されているutfrune
関数は、Goの内部で文字列(UTF-8エンコードされた文字列)の中から特定のルーン(Unicodeコードポイント)を探すために使用される関数です。C言語のstrchr
やwcschr
に似ていますが、UTF-8文字列を適切に扱います。
技術的詳細
このコミットの技術的な核心は、Goコンパイラのインポートパス検証ロジックの変更にあります。具体的には、src/cmd/gc/subr.c
ファイル内のisbadimport
関数が修正されています。
isbadimport
関数は、与えられたインポートパスがGoの規則に違反していないかをチェックする役割を担っています。この関数は、インポートパスに含まれる各文字を走査し、不正な文字が含まれていないかを確認します。
変更前は、この関数内でインポートパスに含めることができない文字のリストにチルダ(~
)が含まれていました。これは、Goのインポートパスが通常、URLのような形式で表現され、特殊文字の使用が制限されるという一般的な慣習に基づいていた可能性があります。
しかし、前述の通り、Windowsのファイルシステムではチルダを含むパスが合法的に存在し、またGo言語の仕様やgo/parser
の挙動がチルダを許容していたため、コンパイラ側でのこの制限は不整合を引き起こしていました。
このコミットでは、isbadimport
関数内の不正文字リストからチルダ(~
)が削除されました。これにより、コンパイラはインポートパスにチルダが含まれていても、それを不正な文字としてフラグ付けしなくなり、Windows環境でのビルド問題が解消されます。
この変更は、Go言語のクロスプラットフォーム互換性を高める上で重要です。特に、WindowsユーザーがGoのソースコードをビルドする際に、ファイルパスの差異によって予期せぬエラーに遭遇するのを防ぎます。また、Go言語の異なるコンポーネント(コンパイラとパーサー)間での挙動の整合性を保つことにも寄与しています。
コアとなるコードの変更箇所
変更はsrc/cmd/gc/subr.c
ファイルの一箇所のみです。
--- a/src/cmd/gc/subr.c
+++ b/src/cmd/gc/subr.c
@@ -3639,7 +3639,7 @@ isbadimport(Strlit *path)
yyerror("import path contains space character: \"%s\"", path->s);
return 1;
}
- if(utfrune("!\"#$%&'()*,:;<=>?[]^`{|}~", r)) {
+ if(utfrune("!\"#$%&'()*,:;<=>?[]^`{|}", r)) {
yyerror("import path contains invalid character '%C': \"%s\"", r, path->s);
return 1;
}
コアとなるコードの解説
上記のコードスニペットは、isbadimport
関数内の特定の条件分岐を示しています。
if(utfrune("!\"#$%&'()*,:;<=>?[]^
{|}~", r)) { ... }` (変更前)if(utfrune("!\"#$%&'()*,:;<=>?[]^
{|}", r)) { ... }` (変更後)
この行は、インポートパスの各ルーン(r
)が、指定された不正文字の集合に含まれているかどうかをチェックしています。utfrune
関数は、第一引数で与えられた文字列(この場合は不正文字の集合を表す文字列リテラル)の中に、第二引数で与えられたルーンr
が存在するかどうかを調べます。存在すれば真を返し、yyerror
関数を呼び出してエラーメッセージを出力し、1
を返して不正なインポートパスであることを示します。
変更前は、不正文字の集合を表す文字列リテラルにチルダ(~
)が含まれていました。これが、インポートパスにチルダが含まれる場合にエラーとなる原因でした。
変更後、この文字列リテラルからチルダ(~
)が削除されています。これにより、utfrune
関数がチルダに対して真を返すことがなくなり、インポートパスにチルダが含まれていてもエラーとして扱われなくなりました。
この修正は非常に局所的ですが、Goコンパイラのインポートパス処理における重要な挙動変更であり、Windows環境での互換性問題を解決する上で不可欠な変更でした。
関連リンク
- Go Language Specification: https://go.dev/ref/spec (特に "Import declarations" のセクション)
- Go
go/parser
package documentation: https://pkg.go.dev/go/parser - Go CL 5777073 (Gerrit Change-Id): https://golang.org/cl/5777073 (これはコミットメッセージに記載されているGerritの変更リストへのリンクです。GoプロジェクトではGitHubにプッシュされる前にGerritでコードレビューが行われます。)
参考にした情報源リンク
- Windows 8.3 filename: https://en.wikipedia.org/wiki/8.3_filename
- Go source code (for context on
src/cmd/gc/subr.c
andutfrune
): https://github.com/golang/go - General understanding of Go compiler and import paths.
- Web search results for "Go compiler gc import paths tilde Windows ADMIN~1" (used to confirm the context of Windows 8.3 filenames and their interaction with Go import paths).