Swift 2.2 Released! より SE-0020: Swift の言語のバージョンのビルドコンフィギュレーション です。
原文に従ってこの訳は Apache License 2.0 とします。
ツッコミお待ちしています。
Swift の言語のバージョンのビルドコンフィギュレーション
- 提案: SE-0020
- 著者: David Farler
- ステータス: Swift 2.2 で 実装された
- レビューマネージャ: Doug Gregor
はじめに
この提案は Swift 2.2 に #if swift
という新しいビルドコンフィギュレーションのオプションを加えようとするものです
動機
時とともに Swift の文法は変化するかもしれません。しかし、ライブラリやパッケージの作者は自分たちのコードが言語の複数のバージョンで動くことを望むでしょう。これまで開発者が持つ唯一の頼みの綱は言語のバージョンごとに別個のリリースブランチを作って維持するという方法でした。このため開発者は複数のソースツリーを維持しなくても文法の変化に追従できる別のツールを使いました。
私たちはソースコードを配布しているパッケージの作者にとっても言語のリビジョン間の移行を容易なものとし、それらのユーザーが古い Swift でも新しい Swift でもビルドできるようにしたいと思います。
提案手法
この簡単な例で十分に例示できます:
#if swift(>=2.2)
print("Active!")
#else
this! code! will! not! parse! or! produce! diagnostics!
#endif
詳細設計
これは既にコンパイラの中に存在するバージョンに関する仕組みを使います。言語のバージョンはビルド時にコンパイラに埋め込まれているので、コードの中のどのブロックを有効にするべきかはわかります。言語のバージョンが少なくとも条件で指定されたものと同じなら、有効になる部分がパースしてコンパイルされ、コードに組み込まれます。
他のビルドコンフィギュレーションのと同じように #if swift
は行ベースではありません。文や宣言全体を含みます。しかし、他とは異なり、#if swift
で囲われた無効な部分はパースしません。もしくは診断メッセージを出力します。これにより他のバージョンの Swift 用の文法的に異なるコードをひとつのソースファイルに記述できます。
現在のところ、バージョンのコンポーネントは二つまでをだけを想定します。+0.0.1 のリビジョンの違いで文法的な変更は起きないだろうと思われるためです。
コンフィギュレーション関数の引数は単一項の前置式で、簡単のために想定する演算子は >=
ひとつです。必要になった場合には、他の比較演算子を含むように拡張できます。
既存のコードに対する影響
この仕組みはオプトインなので、この変更は既存のコードに影響しないでしょう。
検討された代替案
バージョン引数について他に二つのフォーマットを検討しました:
- 文字列リテラル (#if swift("2.2")
): 任意の数のバージョンのコンポーネントを埋め込むことができますが、マイクロリビジョンでの文法の変更は起きにくいと考えられます。もし別のバージョンのコンポーネントが必要になっても、パーサーの変更は大きなものではありません。
- ただの数値 (#if swift(2.2)
): >=
が妥当なデフォルトですが、どのような比較を行うのか明確ではありません。==
である思われるかもしれません。
- 引数リスト (#if swift(2, 2)
): 柔軟性の高い方法ですが、二つ目の 2
がバージョン全体を表すコンポーネントではなく、異なる意味を持つ引数かもしれないことを示唆してしまう可能性があります。