kotlinkotlinpoet

How to get the type of an instance of javax.lang.model.element.Element


I'm following Hello World of Annotation Processing in Kotlin and KotlinPoet's documentation and am trying to implement a generic builder for Kotlin. I'd like to generically create a method for every field in an annotated data class and give it's argument the same name and type of the field. The problem is that I cannot find which type the field has, given the instance of javax.lang.model.element.Element that I have. Here's what I managed that far:

fieldsIn(klass.enclosedElements)
            .forEach {
                classBuilder
                        .addProperty(PropertySpec
                                .builder(it.toString(), String::class, KModifier.INTERNAL)
                                .mutable(true)
                                .initializer("\"\"")
                                .build())

                classBuilder
                        .addFunction(FunSpec
                                .builder(it.toString())
                                .addParameter(ParameterSpec
                                        .builder(
                                                it.toString(), 
                                                it.?) // what to use here?
                                        .build())
                                .build())
            }

How can I find the type of the field? I read in the documentation that you should use method asType() but this return an instance of TypeMirror. I can't really see how to continue from here. Any suggestions are welcome.


Solution

  • I ended up using this function:

    private fun getClass(it: VariableElement): KClass<*> {
        val type = it.asType()
    
        return when (type.kind) {
            TypeKind.DECLARED -> Class.forName(type.toString()).kotlin
            TypeKind.BOOLEAN -> Boolean::class
            TypeKind.BYTE -> Byte::class
            TypeKind.SHORT -> Short::class
            TypeKind.INT -> Int::class
            TypeKind.LONG -> Long::class
            TypeKind.CHAR -> Char::class
            TypeKind.FLOAT -> Float::class
            TypeKind.DOUBLE -> Double::class
            else -> throw Exception("Unknown type: $type, kind: ${type.kind}")
        }
    }