18cd3c9bceb185c21022a0ea1501d723f7bc503b
1 package ru.fredboy.cavedroid.ksp.processor
3 import com.google.devtools.ksp.processing.*
4 import com.google.devtools.ksp.symbol.KSAnnotated
5 import com.google.devtools.ksp.symbol.KSClassDeclaration
6 import com.google.devtools.ksp.symbol.KSType
7 import com.squareup.kotlinpoet.*
8 import com.squareup.kotlinpoet.ksp.toClassName
9 import com.squareup.kotlinpoet.ksp.writeTo
10 import ru.fredboy.cavedroid.ksp.annotations.GenerateSetMultibindingsModule
12 class GenerateSetMultibindingsSymbolProcessor(
13 private val codeGenerator: CodeGenerator,
14 private val logger: KSPLogger,
15 ) : SymbolProcessor {
17 private fun generateModule(
18 interfaceName: ClassName,
19 moduleName: ClassName,
20 classes: List<ClassName>
21 ): FileSpec? {
22 if (classes.isEmpty()) {
23 return null
24 }
26 val bindings = classes.map { clazz ->
27 FunSpec.builder("bind${clazz.simpleName}")
28 .addAnnotation(ClassName("dagger", "Binds"))
29 .addAnnotation(ClassName("dagger.multibindings", "IntoSet"))
30 .addParameter(ParameterSpec("impl", clazz))
31 .returns(interfaceName)
32 .addCode("return impl")
33 .build()
34 }
36 val moduleObject = TypeSpec.objectBuilder(moduleName)
37 .addAnnotation(ClassName("dagger", "Module"))
38 .addFunctions(bindings)
39 .build()
41 return FileSpec.builder(moduleName)
42 .addType(moduleObject)
43 .build()
45 }
47 private fun processAnnotation(resolver: Resolver, annotation: KSClassDeclaration) {
48 val args = annotation.annotations.first {
49 it.shortName.getShortName() == "GenerateSetMultibindingsModule"
50 }.arguments.takeIf { it.size == 3 } ?: run {
51 logger.error("GenerateSetMultibindingsModule should have 3 arguments")
52 throw IllegalArgumentException()
53 }
55 val interfaceName = args.first { it.name?.getShortName() == "interfaceClass" }.value as KSType
56 val modulePackage = args.first { it.name?.getShortName() == "modulePackage" }.value as String
57 val moduleName = args.first { it.name?.getShortName() == "moduleName" }.value as String
59 val moduleClassName = ClassName(modulePackage, moduleName)
60 val elements = resolver.getSymbolsWithAnnotation(annotation.qualifiedName!!.asString())
61 .filterIsInstance<KSClassDeclaration>()
62 .map(KSClassDeclaration::toClassName)
63 .toList()
65 logger.info("Found elements: ${elements.joinToString()}")
67 generateModule(
68 interfaceName = interfaceName.toClassName(),
69 moduleName = moduleClassName,
70 classes = elements
71 )?.writeTo(codeGenerator, Dependencies(true))
72 }
74 override fun process(resolver: Resolver): List<KSAnnotated> {
75 val annotations = resolver.getAnnotatedClasses(GenerateSetMultibindingsModule::class.qualifiedName!!, logger)
76 logger.info("Found annotations: ${annotations.joinToString { it.qualifiedName!!.asString() }}")
77 annotations.forEach { processAnnotation(resolver, it) }
78 return emptyList()
79 }
81 }