Swift Digest
ST-0020 | Swift Evolution

SourceLocationfilePath プロパティを追加する

Add a filePath property to SourceLocation

Proposal
ST-0020
Authors
Jonathan Grynspan
Review Manager
Rachel Brindle
Status
Implemented (Swift 6.3)

このダイジェストはClaude Opus 4.7 / 4.8によって生成されたものです(License)。原文はこちら

01 何が問題だったのか

Swift Testing では、テスト・問題・エラーなどがソース上のどこに位置するかを SourceLocation という構造体で表現します。SourceLocation は行・列に加えて、Swift の file ID#fileID で得られる モジュール名/ファイル名 形式の文字列)を保持しています。

設計当初は、Visual Studio Code や Xcode などのツール側で file ID をファイルパスに変換できるという前提に立っていました。また、Swift 6 で #filePath が deprecated になる可能性も視野に入れ、SourceLocation には fileID プロパティだけを公開し、内部では収集していたファイルパスは公開しないという判断がなされました。

しかし、Swift 6 のリリース後も #file / #fileID / #filePath の扱いは現状維持となり、状況が次のように変わってきました。

  • ツール側にとっては file ID よりもファイルパスの方が扱いやすい場面が多い
  • 開発者の環境上の元ファイルへ file ID から変換するのは、サンドボックスが厳しいツールでは困難または不可能なケースがある
  • Objective-C や C++ など Swift 以外の言語から JSON event stream に source location を流し込みたいときに、file ID 相当の値を組み立てるのは現実的ではない

SourceLocation 自体はコンパイル時にフルパスを取得しているにもかかわらず、それを実行時に取り出す公開 API がないことが、これらのユースケースの障害になっていました。

02 どのように解決されるのか

SourceLocationfilePath プロパティを追加し、JSON event stream のスキーマにも対応するキーを追加します。

SourceLocation.filePath

SourceLocation に、ソースファイルのパスを表す get/set 可能な filePath プロパティが追加されます。

extension SourceLocation {
  /// The path to the source file.
  public var filePath: String { get set }
}

filePath の値は絶対パスですが、実行時にそのパスにファイルが存在することは保証されません(たとえばビルドシステム上に存在し、実行環境には存在しない場合があります)。パスの形式(POSIX、Windows など)も実装定義です。

JSON event stream のスキーマ

JSON event stream のスキーマバージョン "6.3" 以降で、source location を表すオブジェクトに "filePath" キーが追加されます。あわせて、これまで必須だった "fileID" キーがオプショナルになります。

 <source-location> ::= {
-  "fileID": <string>, ; the Swift file ID of the file
+  ["fileID": <string>,] ; the Swift file ID of the file if available, as per
+                        ; SE-0274 § "Specification of the #file string format"
+  "filePath": <string>, ; the compile-time path to the file
   "line": <number>,
   "column": <number>,
 }

"filePath" の値も同じく絶対パスで、ファイルの存在やパス形式についての保証は API 側と同様です。

"fileID" の省略時の挙動

JSON 側で "fileID" が省略されている SourceLocation を Swift Testing がデコードするときには、"filePath" から file ID が合成されます。このとき、モジュール名は "__C" と仮定されます(Swift コンパイラ・ランタイムが Objective-C / C などからインポートされた型に対して用いるモジュール名です)。

これにより、Objective-C や C++ など Swift 以外の言語からも source location を構築しやすくなります。たとえば Objective-C からは次のように書けます。

id jsonObject = @{
  @"line": @(__LINE__),
  @"column": @(__builtin_COLUMN()),
  @"filePath": @(__file__)
};

__file__"/foo/bar/quux.m" の場合、Swift Testing 側では file ID として "__C/quux.m" が推論されます。

ツール連携と移行

これまで内部的に出力されていた未サポートの "_filePath" キーは、エコシステム全体が "filePath" に移行するまでの間は引き続き併記されます。ツール側は、新しい "filePath" キーを参照するように移行することが推奨されます。