Pushing the limits of Kotlin annotation processingを読んだ。
よくまとまっている。
ちょっとこの記事をなぞって感想文を書きます。
kapt
kaptはKotlinがJavaのAnnotation Processingをサポートするよというツール。kaptはkapt1とkapt2とkapt3がある。
kapt3以降はもう多分作んないって前に作ってる人が言ってた。(kapt4とかは多分でないよってこと)
Kotlin M12以前
「Kotlinは良いらしいけどAnnotation Processingを利用したライブラリは使えないよね」みたいな話はよくあった(観測範囲で)。
Android前提においてDagger2とかData Bindingとか、
開発を補うための仕組みで確かに便利なものなんだけど
Kotlin使うならAnnotation Processingは難しい。
個人的にはそこは捨ててKotlinで書くという選択もありだなと思っていた(し今も割とそう思っている)。
それはAnnotation Processingライブラリを捨てても劣らないぐらいの言語の表現力がある気がするから。たぶん。
Kotlin M12以降(kapt1)
ここ(Pushing the limits of Kotlin annotation processing)に
書いてあるとおり、kaptはKotlinのM12で突然現れた。
なんかめっちゃすごいスピード感で登場したので個人的に驚いたのを覚えている。
KotlinはJavaのサーバーサイドやJavaFX、Swingといったデスクトップアプリの代替言語としても利用できるけど、この動きはAndroidの開発を意識したものだろうかなぁというのはとても伝わった。
その当時(と言っても1年ちょい前ぐらい)、
「Dagger2で制限はあるけど動くぜ」ぐらいだったけど僕としてはそれだけでも割りとすごいなーと思ってた。
Annotation ProcessingをサポートしているJVM言語ってあんまりないと思う。(あったら教えてほしい。単純に知りたい)
だって、JVM言語自体がコンパイルタイムに介入するもので、さらにその上にAnnotation Processingが動くってなかなかすごいなぁと思うんですよね。
(あーでもマクロとか持ってる言語ならあるか)
generate stub
コンパイルタイムにAnnotation Processingで生成されたクラスが参照できないみたいな問題が出て、あらかじめmethodのシグネチャを持つスタブのクラスを作るようなオプションが追加された。
https://blog.jetbrains.com/kotlin/2015/05/kapt-annotation-processing-for-kotlin/
これで、上手く動かない問題も解決されたりしていた。まぁそれでもうまくいかないんですっていうのも見た気がする。
Kotlin 1.0.4(kapt2)
Kotlin 1.0.4でkapt2が出た
(2017/02現在、Kotlnは1.0.6がstableな最新バージョンで、1.1のベータ2が出ているところだったと思う)。
でもIntelliJ PlatformのASTを使ったらちょっと遅くなってしまったのですぐに作り変えることになった。
Kotlin 1.0.6(kapt3)
kapt3が出た。kapt2とは全く別の実装らしい。主にパフォーマンスの問題を解決するための対応だと思う。
2つの問題
1.アノテーションつきのKotlinコードへの対応
Annotationの付与されたKotlinコードはJavaコードのように見えるが、メタデータを読むための公式な方法がない。つまり、Kotlinコードにアノテーションついてても情報読めないという感じ。たぶん。
2.複数のroundのサポート
Annotation Processingでは前回のroundからJavaのソースコードやclassファイルの情報を取って次のroundを動かすような動きがある。roundがなくなるまでたらい回しにされるような動き。これに関してkapt3では対応していなくてissueが上がっている状態。
https://youtrack.jetbrains.com/oauth?state=%2Fissue%2FKT-14070
ワークアラウンドでの対処としては、Gradleで複数moduleを作ってroundを開発者側で管理することっぽい。
https://github.com/Takhion/generate-kotlin-multiple-rounds
どう使うか
という感じで色々途上ではあるけど、単純にスゴイなぁと言うのが個人的には勝っている。あと、これって結構開発するの難しいんじゃないかなぁと思っている。
だから、いろんなユースケースで問題があればissueを上げて皆で良くしてくのが良いんじゃないかと思う。
現状はKotlinを入れてみて、その上にDagger2とか乗せていくのが現実的で、JavaとDagger2とかでガンガン書いてるプロジェクトをKotlinに全部置き換えたりするのはしんどいんじゃない?って思う。
それだったら新規案件で使うか、全部捨てて作り直す。
それがしんどいようだったら部分的にKotlinに置き換える(テストコード、POJOなど)かKotlinを使わない。
本当にkaptの問題?
ってたまに思うことはあって、それJavaでも動かないんじゃない?ってこともある。例えばジェネリックな返り値を持ったメソッド書いたらDagger2で上手く動かないとかJavaでも出くわしたりした。
あと、Kotln抜きにしても複数のAnnotation Processingのライブラリを使うってのは上手く動かないリスク上がったりするんじゃないかなぁとは思う。
それにプラスKotlinのcompileフェーズ入ったら難しいよねぇとか思うとまぁ、そこを想像すると僕は暖かく見守る方向になる。
ドキュメントはあったほうが良い
本当にkaptの問題かわかんないから、kaptのドキュメントは合ったほうが良いと思う。
今は仕様の公式ドキュメントがないみたい。
多分今が開発途中だからというのもあると思うんだけど、仕様が明示されてればここは可能/不可能も分かるし、
どういう理屈で動いてるのかも分かってもらえる気がするし。
結論
面白いし応援しよう!
0 件のコメント:
コメントを投稿