package moe.nea.firmament.annotations.process import com.google.auto.service.AutoService import com.google.devtools.ksp.processing.CodeGenerator import com.google.devtools.ksp.processing.Dependencies import com.google.devtools.ksp.processing.KSPLogger import com.google.devtools.ksp.processing.Resolver import com.google.devtools.ksp.processing.SymbolProcessor import com.google.devtools.ksp.processing.SymbolProcessorEnvironment import com.google.devtools.ksp.processing.SymbolProcessorProvider import com.google.devtools.ksp.symbol.KSAnnotated import com.google.devtools.ksp.symbol.KSClassDeclaration import com.google.devtools.ksp.symbol.KSName class CompatMetaProcessor(val logger: KSPLogger, val codeGenerator: CodeGenerator, val sourceSetName: String) : SymbolProcessor { override fun process(resolver: Resolver): List { val files = resolver.getAllFiles().toList() val packages = files.mapTo(mutableSetOf()) { it.packageName.asString() } packages.add("moe.nea.firmament.annotations.generated.$sourceSetName") val compatMeta = resolver.getSymbolsWithAnnotation("moe.nea.firmament.util.compatloader.CompatMeta") .singleOrNull() as KSClassDeclaration? ?: return listOf() val dependencies = Dependencies(aggregating = true, *files.toTypedArray()) val generatedFileName = "GeneratedCompat${sourceSetName.replaceFirstChar { it.uppercaseChar() }}" val compatFile = codeGenerator.createNewFile(dependencies, "moe.nea.firmament.annotations.generated.$sourceSetName", generatedFileName) .bufferedWriter() compatFile.appendLine("// This file is @generated by SubscribeAnnotationProcessor") compatFile.appendLine("// Do not edit") compatFile.appendLine("package moe.nea.firmament.annotations.generated.$sourceSetName") compatFile.appendLine("class $generatedFileName : moe.nea.firmament.util.compatloader.ICompatMetaGen {") compatFile.appendLine(""" override fun owns(className: String): Boolean { return moe.nea.firmament.util.compatloader.CompatHelper.isOwnedByPackage(className, ${ packages.joinToString { "\"" + it + "\"" } }) } override val meta: moe.nea.firmament.util.compatloader.ICompatMeta get() = ${compatMeta.qualifiedName!!.asString()} """) compatFile.appendLine("}") compatFile.close() val metaInf = codeGenerator.createNewFileByPath( dependencies, "META-INF/services/moe.nea.firmament.util.compatloader.ICompatMetaGen", extensionName = "") .bufferedWriter() metaInf.append("moe.nea.firmament.annotations.generated.$sourceSetName.") metaInf.appendLine(generatedFileName) metaInf.close() return listOf() } @AutoService(SymbolProcessorProvider::class) class Provider : SymbolProcessorProvider { override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor { return CompatMetaProcessor(environment.logger, environment.codeGenerator, environment.options["firmament.sourceset"] ?: "main") } } }