6bcb60cad518c57e7e234d231462a4b64c176752
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 .addAnnotation(
39 AnnotationSpec.builder(ClassName("javax.annotation.processing", "Generated"))
40 .addMember("value = [%S]", this::class.qualifiedName!!)
41 .build()
42 )
43 .addFunctions(bindings)
44 .build()
46 return FileSpec.builder(moduleName)
47 .addType(moduleObject)
48 .build()
50 }
52 private fun processAnnotation(resolver: Resolver, annotation: KSClassDeclaration) {
53 val args = annotation.annotations.first {
54 it.shortName.getShortName() == "GenerateSetMultibindingsModule"
55 }.arguments.takeIf { it.size == 3 } ?: run {
56 logger.error("GenerateSetMultibindingsModule should have 3 arguments")
57 throw IllegalArgumentException()
58 }
60 val interfaceName = args.first { it.name?.getShortName() == "interfaceClass" }.value as KSType
61 val modulePackage = args.first { it.name?.getShortName() == "modulePackage" }.value as String
62 val moduleName = args.first { it.name?.getShortName() == "moduleName" }.value as String
64 val moduleClassName = ClassName(modulePackage, moduleName)
65 val elements = resolver.getSymbolsWithAnnotation(annotation.qualifiedName!!.asString())
66 .filterIsInstance<KSClassDeclaration>()
67 .map(KSClassDeclaration::toClassName)
68 .toList()
70 logger.info("Found elements: ${elements.joinToString()}")
72 generateModule(
73 interfaceName = interfaceName.toClassName(),
74 moduleName = moduleClassName,
75 classes = elements
76 )?.writeTo(codeGenerator, Dependencies(true))
77 }
79 override fun process(resolver: Resolver): List<KSAnnotated> {
80 val annotations = resolver.getAnnotatedClasses(GenerateSetMultibindingsModule::class.qualifiedName!!, logger)
81 logger.info("Found annotations: ${annotations.joinToString { it.qualifiedName!!.asString() }}")
82 annotations.forEach { processAnnotation(resolver, it) }
83 return emptyList()
84 }
86 }