SwiftGenを使うと、翻訳ファイル等の入力からテンプレートを通して型付きのコードが得られるというツールがある。
この考えを応用して、
I18n.t('foo.bar.baz')
を
L10n.foo.bar.baz
と書けたら、
- 重複定義があったらRubyでエラーになるはずなので気付ける
- 型も同時に生成したらLSP的に便利そう
と思って書いてみた。
https://gist.github.com/ksss/b1988f09940617896a1f9ff3968975a2
以下のようなRubyと、
module L10n def self.foo = Foo module Foo def self.bar = Bar module Bar def self.baz = I18n.t('foo.bar.baz') end end end
以下のようなRBSを出力する。
module L10n def self.foo = singleton(Foo) module Foo def self.bar = singleton(Bar) module Bar def self.baz: () -> String end end end
L10n. # ここでfooが候補に出る L10n.foo. # ここでbarが候補に出る L10n.foo.bar.baa # baa methodは無いので型チェックで見つかる L10n.foo.bar.baz # Stringが返ることが分かる
確かに目論見自体は良かったが、以下の点がイマイチだった。
- 出力が数万行になり、無駄が多そう
- viewは大抵テンプレートエンジン上の記述でありsteep未対応
I18n.t('foo.#{var}.title')的な動的記述が結構ある
SwiftGenは、言語の型による強制力が十分にあり、かつ課題がハッキリしているのでうまくいっているんだろうなあ。