https://kotlinlang.org logo
Title
p

PixelHamster

02/26/2022, 3:37 PM
Hi, when processing annotations can I somehow know when it processed the last annotation so I can write the end of a file and close it ?
To give some context, this is my processor at the moment But as you the symbols.isNotEmpty() is not a working indicator as process is called again afterwards
package me.melijn.annotationprocessors.injector

import com.google.devtools.ksp.processing.*
import com.google.devtools.ksp.symbol.KSAnnotated
import com.google.devtools.ksp.symbol.KSClassDeclaration
import com.google.devtools.ksp.symbol.KSFunctionDeclaration
import com.google.devtools.ksp.symbol.KSVisitorVoid
import com.google.devtools.ksp.validate
import me.melijn.annotationprocessors.util.appendText

class InjectorProcessor(
    codeGenerator: CodeGenerator,
    val logger: KSPLogger
) : SymbolProcessor {

    val injectKoinModuleFile = codeGenerator.createNewFile(Dependencies(false), "me.melijn.bot", "InjectorKoinModule")

    init {
        injectKoinModuleFile.appendText("package me.melijn.bot\n\n")
        injectKoinModuleFile.appendText(
            """
                import org.koin.dsl.bind
                import org.koin.dsl.module
               """.trimIndent()
        )
        injectKoinModuleFile.appendText("\nobject InjectionKoinModule {\n\n")
        injectKoinModuleFile.appendText("    val module = module {\n")
    }

    override fun process(resolver: Resolver): List<KSAnnotated> {
        val symbols = resolver.getSymbolsWithAnnotation("me.melijn.annotationprocessors.injector.Inject").toList()
        val ret = symbols.filter { !it.validate() }.toList()
        symbols
            .filter { it is KSClassDeclaration && it.validate() }
            .forEach { it.accept(InjectorVisitor(), Unit) }
        if (symbols.isNotEmpty()) {
            injectKoinModuleFile.appendText("    }\n")
            injectKoinModuleFile.appendText("}\n")
            injectKoinModuleFile.close()
        }
        return ret
    }


    inner class InjectorVisitor : KSVisitorVoid() {
        override fun visitClassDeclaration(classDeclaration: KSClassDeclaration, data: Unit) {
            classDeclaration.primaryConstructor!!.accept(this, data)
        }

        override fun visitFunctionDeclaration(function: KSFunctionDeclaration, data: Unit) {
            val parent = function.parentDeclaration as KSClassDeclaration

            val className = parent.qualifiedName?.asString() ?: throw IllegalStateException("Annotation not on class ?")
            injectKoinModuleFile.appendText("         single { $className(${function.parameters.joinToString(", ") { "get()" }}) } bind $className::class\n")
        }
    }
}
j

Jiaxiang

02/28/2022, 5:43 AM
there is a
SymbolProcessor.finish()
function that will be executed after process is done, will that serve your purpose?