特に下調べせずKSPを触り始めたところ、色々ハマりました。
大体は公式ドキュメントをちゃんと読めば解決する内容です。
ハマりながら書いたSymbolProcessor: https://github.com/tkhskt/ShaderView/tree/feature/kotlin_dsl_interface/processor
環境
Kotlin: 1.6.10
KSP: 1.6.10-1.0.4
KotlinPoet: 1.10.2
ハマったこと
コード生成されない
SymbolProcessorを実装するモジュールでは、resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider
を作成する必要があります。
resources/services/com.google.devtools.ksp.processing.SymbolProcessorProvider
(META-INFが抜けてる)だと、ProcessorProviderは認識されるようでしたが、Processorを使用するモジュールにコードが生成されませんでした。
インクリメンタルビルドすると生成されたコードが消える
KSP関連の記事を見ていると、こんな感じ↓でファイル(コード)を生成していることが多いですが、これだとIncremental Buildを行った際に前回生成したコードが消えてしまいます。
val file = codeGenerator.createNewFile(
Dependencies(false),
"com.hoge",
"Hoge"
)
file.write(code.toByteArray())
file.close()
これを回避するためには、Dependencies
にsource: KSFile
を渡します。
val file = codeGenerator.createNewFile(
Dependencies(false, classDeclaration.containingFile!!), // KSFileを渡す
"com.hoge",
"Hoge"
)
file.write(code.toByteArray())
file.close()
このあたりの挙動は下記の動画が非常に参考になります。
https://youtu.be/sJfURbrdau0
KotlinPoetだと下記のようになります。
val file = FileSpec.builder(packageName, className)
...
.build()
file.writeTo(codeGenerator, Dependencies(false, classDeclaration.containingFile!!))
生成されたコードがIDE(AndroidStudio)で認識されない
KSPを使用するモジュールのbuild.gradle
のandroidブロックにsourceSets
の設定を追加します。
android {
applicationVariants.all { variant ->
kotlin.sourceSets {
def name = variant.name
getByName(name) {
kotlin.srcDir("build/generated/ksp/$name/kotlin")
}
}
}
}
パッケージ名をどうやって管理するか問題
KSPとは直接関係ないのですが、Processorで使うパッケージ名/クラス名をどうやって管理するか悩みました。
airbnb/epoxyのProcessorで採用されている方法が良い感じでした。(airbnb/epoxy/processor/ClassNames.kt)
object ClassNames {
private const val PKG_SHADER_VIEW = "com.appspell.shaderview"
private const val PKG_SHADER_VIEW_GL_PARAMS = "com.appspell.shaderview.gl.params"
private const val PKG_SHADER_VIEW_KTX_ANNOTATION = "com.appspell.shaderview.ktx.annotation"
...
val SHADER_VIEW = ClassName(PKG_SHADER_VIEW, "ShaderView")
val SHADER_PARAMS = ClassName(PKG_SHADER_VIEW_GL_PARAMS, "ShaderParams")
val SHADER_PARAMS_BUILDER = ClassName(PKG_SHADER_VIEW_GL_PARAMS, "ShaderParamsBuilder")
val SHADER_PARAMETERS = ClassName(PKG_SHADER_VIEW_KTX_ANNOTATION, "ShaderParameters")
...
}
参考
- KSPドキュメント
- KSPの使い方
- IDEで認識されない問題について
- KotlinPoet