背景
RBSも利用が増えてくると、細かい"こうしたほうがいい"が出てくることがあると予想される。
例えば、
- インデント
initialize
の返り値はvoidを使うuntyped?
ではなくuntyped
を使う- メソッド引数に
void
を使わない
などなど。
こうしたことを指摘するツールとしては、Rubyではrubocopが覇権をとっており、大体の環境ですでに使われている。
このエコシステムにRBSも乗っかりたい。
問題点
VSCode上で警告を表示できない
大きな問題点として、VSCode上の波線(squigglyというらしい)が表示できないという問題がある。
エディタでインタラクティブに問題点が見える体験はかなり重要だと思っているので対応したい。
しかしながら何が原因なのかはわからない。
試しにrubocop orgが公式にホストしているrubocop-mdを使ってみたが、こちらも特にエディタ上ではなにも表示されなかった(ruby-lsp)。
原因を究明するのに時間を使うべきか、より機能追加に時間を使うべきか、悩みどころである。
名前をrubocop-rbsにできない
今回作っているものはrubocop-rbsと言うしかないものなのだが、
rubocop-rbsというgemはすでに存在している。
これはRBSを見て、Ruby側のメソッド定義の引数の形式と数のマッチングをみるもののようだ。
名前は早い者勝ちなのでしょうがないが、この作っているものの名前に悩んでいる。
今は仮にrubocop-rbs-sig
としている。
機能
とりあえず、
- シンタックスエラー表示
initialize
の返り値はvoidを使うuntyped?
ではなくuntyped
を使う
はできた。
sig/rubocop/rbs/sig.rbs:5:31: C: [Correctable] RBS/Sig/InitializeReturnType: #initialize method should return void def initialize: () -> nil ^^^ sig/rubocop/rbs/sig.rbs:6:19: C: [Correctable] RBS/Sig/Untyped: untyped? should be untyped def foo: (untyped?) -> (Integer | untyped) ^^^^^^^^ sig/rubocop/rbs/sig.rbs:6:33: C: [Correctable] RBS/Sig/Untyped: Integer | untyped should be untyped def foo: (untyped?) -> (Integer | untyped) ^^^^^^^^^^^^^^^^^
- autocorrect
- 機能別にCopを分ける
といったこともできている。
実装方法
rubocopはRubyに特化したツールであり、RBSはRubyとは違う。
Ruby以外のファイルにrubocopを実行する参考例としては、rubocop-erbやrubocop-mdがみつかった。これを参考にした。
rubocopではターゲットファイルがRubyとしてパースできなかった場合、on_other_file
を呼び出すようになっている。
このon_other_file
でRBSとしてパースし、パースできたらRBSとして扱うようにしてみている。
Rubyとしてパースして、RBSとしてもパースしているので無駄はある気はするが、ここを変えようとするとrubocopにかなり無茶させないといけなくなり、コード量も増える気がするので一旦こうしている。
つまり
やればできそう。