Overview
I'm trying to build my first annotation processor and it's going pretty well. I am creating a code generating processor that basically generates SharedPreferences
for a defined interface. My current annotations are SharedPrefs
and Default
. @SharedPrefs
informs the processor that the file is an interface and needs a generated prefs file. @Default
is what I annotated some properties in the interface as in order to let the processor know what to set the default value to. There can be multiple files defined as @SharedPrefs
.
Implementation
I currently use the following code to get a list of files annotated with @SharedPrefs
and the @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]")
In Use:
@SharedPrefs
interface InstanceSettings {
var wifiPassword: String
@Default("20")
var count: Int
}
Problem
As is, the inner forEach
is returning all properties from all files annotated with @Default
. The code generation works fine, but this doesn't seem like the best way forward. Is there a way to get just the properties w/in the current @SharedPrefs
class that I'm processing? For instance, something like:
roundEnv.getElementsAnnotatedWith(SharedPrefs::class.java)?.forEach { element ->
...
element.methodToGetAnnotatedProperties(Default::class.java)?.forEach {
...
}
}
* EDIT *
I found that, for methods that I annotate
@SomeAnnotation
fun someMethod()
I can loop through the element.enclosingElements
and find if it has an annotation using enclosingElement.getAnnotation(<SomeAnnotation::class.java>)
. Unfortunately, and correct me if I'm wrong here, I can't annotate interface variables with an annotation with AnnotationTarget.FIELD
since they don't have a backing field since it's an interface and they're not implemented. Therefore, I'm using AnnotationTarget.PROPERTY
. When looping through the enclosing elements, all of the variables show up as getters and setters. For the example above for InstanceSettings
, I get getWifiPassword
, setWifiPassword
, getCount
and setCount
. I do not get an element for just wifiPassword
or count
. Calling getAnnotation(Default::class.java)
will always return null on these since they are generated.
Also, any other resources on annotation processing that anyone knows of would be a great addition in the comments. Thanks!