Search code examples
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}")
        }
    }