Как получить тип экземпляра javax.lang.model.element.Element

Я читаю Hello World of Annotation Processing in Kotlin и документацию KotlinPoet, и я пытаюсь реализовать универсальный конструктор для Kotlin. Я хотел бы в общем случае создать метод для каждого поля в аннотированном классе данных и дать его аргументу то же имя и тип поля. Проблема в том, что я не могу найти тип поля, учитывая экземпляр javax.lang.model.element.Element, который у меня есть. Вот что мне удалось до сих пор:

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())
            }

Как узнать тип поля? Я прочитал в документации, что вы должны использовать метод asType(), но он возвращает экземпляр TypeMirror. Я действительно не вижу, как продолжить отсюда. Любые предложения приветствуются.


person uzilan    schedule 15.10.2018    source источник


Ответы (2)


В итоге я использовал эту функцию:

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}")
    }
}
person uzilan    schedule 22.10.2018
comment
Как узнать, является ли тип обнуляемым или необнуляемым? Например, как узнать, является ли тип переменной String? или строка - person Mohit Atray; 21.09.2019
comment
Как насчет параметризованных типов, таких как List<Something> ? - person Bhargav; 07.09.2020

person    schedule
comment
вам нужно добавить некоторые пояснения. Публикация только кода может быть бесполезной - person Mr. Alien; 05.03.2019
comment
Проблема состоит в том, чтобы получить cKlass из типа, что можно сделать, как описано в ответе авторов, но Class.forName() будет работать, только если ваш процессорный модуль знает о cKlass, который вы пытаетесь создать. В моей ситуации это не так, но обходной путь с установкой имени %N вместо типа %T и простым добавлением строки ::class - сработал. - person Murdokai; 05.03.2019