1週間前のScalaMatsuriで発表 し、色々と話をしたわけですが、それから数日経ってScala 3対応版のwartremoverリリースして、さらに色々と試行錯誤していたら、以下のようなことに気が付き、
あっ、よく考えたら、Scala 3のlibrary側のQuotes使ったwartremoverでのlinter、tasty inspectorのinterfaceもそのままそれみたいだから、これそのまま再利用出来るのでは???
— Kenji Yoshida (@xuwei_k) March 24, 2022
(compileとは別の任意のタイミングで .tasty ファイルに対してlinter実行が出来るのでは???)https://t.co/lUx65cX94U
やってみたら出来ました、という話。ScalaMatsuriの発表の最後の方で言及していたTASTyの話ですね。その時はこれに全く気がついていなかった。
大体のことをtweetしてしまってるのと、逆に1から全てを説明すると長くなって辛いので、要点だけまとめると
- TASTyとはScala 3から導入された、ほぼ全てのメタ情報が入ったファイル。デフォルトではJVM用のclassファイルと共に、jarの中に埋め込まれる。
- TASTy inspectorとは、そのTASTyファイルを、任意のタイミングでparseして
scala.quoted.Quotes
のAPIを使って、任意の解析が出来るもの(よってlinterなどにうってつけである?)- 任意のタイミングとは、compileの時に、時間の増加や変なエラー発生含めた、一切の悪影響を与えずに済むメリットがある。
- 例えばcompiler pluginとしてはwartremoverを使わずに、普通にcompileが終わった後に、testとlinter実行を別々に並列実行、などが可能になる
- https://github.com/lampepfl/dotty/blob/3.1.1/library/src/scala/quoted/Quotes.scala
- TASTy inspectorはscala3-compilerに依存しており、Scala 3公式リポジトリで、Scala 3本体と同じサイクルで、開発、リリースされている
- https://github.com/lampepfl/dotty/tree/3.1.1/tasty-inspector/src/scala/tasty/inspector
- TASTy inspectorは、compilerに依存はしているが、普通はcompile時に同時に動作させるものではないので、いわゆるcompiler pluginとは微妙に別のものである
- https://repo1.maven.org/maven2/org/scala-lang/scala3-tasty-inspector_3
- https://docs.scala-lang.org/scala3/reference/metaprogramming/tasty-inspect.html
- このblog書いてる時点の安定版である3.1.1や3.1.2-RC3では、わりと致命的なbugがありそうで、明らかに動かなかったり変な動きをするため、今回はNIGHTLYを使っている
- tweetした通りだが、基本的にwartremoverが
scala.quoted.Quotes
を使うように設計したのと、TASTy inspectorがQuotesとそのTreeを渡してくる、という設計になっているので、そのまま動く(ただし現状だとNIGHTLYのみ) - これもtweetしたが、せっかくだからcoursierで色々と任意のjarを取れるようにして、色々なライブラリを試していた(TASTy inspectorにjar丸ごと渡して解析できるメソッドが用意されている)
- (依存増えるので)おそらくsbt的には別のsub projectとしてwartremover本体に入れたいが、どういう形がいいのか?を模索中なため、とりあえず最低限のわかりやすいサンプル切り出したので、それをblogに書いている、という経緯
- ここ数日wartremover関連で色々やったおかげで、関連するようなしないようなbugっぽいものを色々見つけて報告しました