5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

KSPのProcessor実装でハマったこと備忘録

Last updated at Posted at 2022-03-13

特に下調べせず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()

これを回避するためには、Dependenciessource: 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")
   ...
}

参考

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?