Обзор
Я пытаюсь собрать свой первый процессор аннотаций, и он идет довольно хорошо. Я создаю процессор генерации кода, который в основном генерирует SharedPreferences
для определенного интерфейса. Мои текущие аннотации SharedPrefs
и Default
. @SharedPrefs
информирует процессор о том, что файл является интерфейсом и нуждается в сгенерированном файле prefs. @Default
- это то, что я аннотировал некоторые свойства в интерфейсе, чтобы дать процессору понять, как установить значение по умолчанию. Может быть несколько файлов, определенных как @SharedPrefs
.
Реализация
В настоящее время я использую следующий код для получения списка файлов, помеченных @SharedPrefs
и @Default
s:
roundEnv.getElementsAnnotatedWith(SharedPrefs::class.java)?.forEach { element ->
...
roundEnv.getElementsAnnotatedWith(Default::class.java)?.forEach {
...
}
}
@SharedPrefs
:
@Retention(AnnotationRetention.SOURCE)
@Target(AnnotationTarget.CLASS)
annotation class SharedPrefs(val showTraces: Boolean = false)
@Default
:
@Retention(AnnotationRetention.SOURCE)
@Target(AnnotationTarget.PROPERTY)
annotation class Default(val defaultValue: String = "[null]")
Используется:
@SharedPrefs
interface InstanceSettings {
var wifiPassword: String
@Default("20")
var count: Int
}
Проблема
Как есть, внутренний forEach
возвращает все свойства из всех файлов, помеченных @Default
. Генерация кода работает нормально, но это не лучший способ продвижения вперед. Есть ли способ получить только свойства в текущем @SharedPrefs
классе, который я обрабатываю? Например, что-то вроде:
roundEnv.getElementsAnnotatedWith(SharedPrefs::class.java)?.forEach { element ->
...
element.methodToGetAnnotatedProperties(Default::class.java)?.forEach {
...
}
}
* РЕДАКТИРОВАТЬ *
Я обнаружил, что для методов, которые я аннотирую
@SomeAnnotation
fun someMethod()
я могу l oop через element.enclosingElements
и найдите аннотацию, используя enclosingElement.getAnnotation(<SomeAnnotation::class.java>)
. К сожалению, и исправьте меня, если я ошибаюсь, я не могу аннотировать интерфейсные переменные с аннотацией AnnotationTarget.FIELD
, поскольку у них нет поля поддержки, поскольку это интерфейс, и они не реализованы. Поэтому я использую AnnotationTarget.PROPERTY
. При зацикливании вмещающих элементов все переменные отображаются как геттеры и сеттеры. Для приведенного выше примера для InstanceSettings
я получаю getWifiPassword
, setWifiPassword
, getCount
и setCount
. Я не получаю элемент всего за wifiPassword
или count
. Вызов getAnnotation(Default::class.java)
всегда вернет null для них, поскольку они генерируются.
Кроме того, любые другие ресурсы по обработке аннотаций, о которых кто-либо знает, будут отличным дополнением в комментариях. Спасибо!