我无法使用Kotlin处理器生成类

时间:2018-11-09 18:01:43

标签: kotlin

我正在实现一个处理器,以使用自定义注释生成kotlin代码。问题是我找不到将注释与为其声明的字段相关联的方法,也无法找到了解字段是否为可空类型的方法。处理器无法成功生成代码,因为getAnnotationsByType不会返回当前字段的注释(列表为空)。甚至顺序都不是很好,首先传递字段,然后在所有字段之后添加注释。

package it.kfi.xml.binding.processor

import com.google.auto.service.AutoService
import com.squareup.kotlinpoet.*
import it.kfi.xml.binding.annotations.XmlClass
import it.kfi.xml.binding.annotations.XmlProperty
import java.io.File
import java.lang.reflect.Type
import javax.annotation.Nullable
import javax.annotation.processing.AbstractProcessor
import javax.annotation.processing.Processor
import javax.annotation.processing.RoundEnvironment
import javax.lang.model.SourceVersion
import javax.lang.model.element.Element
import javax.lang.model.element.ElementKind
import javax.lang.model.element.TypeElement
import javax.lang.model.element.VariableElement
import javax.lang.model.type.NullType
import javax.lang.model.type.TypeMirror
import javax.print.DocFlavor
import javax.tools.Diagnostic
import kotlin.reflect.KClass
import kotlin.reflect.full.createType



@AutoService(Processor::class)
class XmlBinder : AbstractProcessor() {

    companion object {

        const val KAPT_KOTLIN_GENERATED_OPTION_NAME = "kapt.kotlin.generated"
    }

    override fun getSupportedAnnotationTypes(): MutableSet<String> {

        return mutableSetOf(XmlClass::class.java.name)
    }

    override fun getSupportedSourceVersion(): SourceVersion = SourceVersion.latest()

    override fun process(annotations: MutableSet<out TypeElement>?, roundEnv: RoundEnvironment): Boolean {

        roundEnv.getElementsAnnotatedWith(XmlClass::class.java)
                .forEach {
                    if (it.kind != ElementKind.CLASS) {
                        processingEnv.messager.printMessage(Diagnostic.Kind.ERROR, "Only classes can be annotated")
                        return true
                    }
                    processClass(it)
                }

        return false
    }

    private fun processClass(element: Element) {

        val className = element.simpleName.toString() + "Model"
        val packageName = processingEnv.elementUtils.getPackageOf(element).toString()

        val classBuilder = TypeSpec.classBuilder(className)
        classBuilder.addModifiers(KModifier.PUBLIC)

        val initFromXml = FunSpec.builder("initFromXml")
        initFromXml.addModifiers(KModifier.PUBLIC)
        initFromXml.addParameter(ParameterSpec.builder("xml", String::class).build())

        val properties = element.enclosedElements

        var x: Int = 1

        //Look for elements annotated with XmlField and add those elements to the generated class
        for (property in properties) {

            val annotation = property.getAnnotationsByType(XmlProperty::class.java)

            val v = 10

            classBuilder.addProperty(PropertySpec.varBuilder(property.simpleName.toString(), String::class, KModifier.PUBLIC).initializer(v.toString()).build())
            initFromXml.addStatement("this.${property.simpleName} = \"${v.toString()}\"")

        }

        classBuilder.addFunction(initFromXml.build())

        val fileName = "kfi_generated_$className"
        val file = FileSpec.builder(packageName, fileName).addType(classBuilder.build()).build()

        val kaptKotlinGeneratedDir = processingEnv.options[KAPT_KOTLIN_GENERATED_OPTION_NAME]
        file.writeTo(File(kaptKotlinGeneratedDir))
    }


}

有人可以帮我找到一种将注释与其字段或属性相关联的方法吗?

0 个答案:

没有答案