https://kotlinlang.org logo
#kapt
Title
# kapt
s

SnowmanX95

05/28/2019, 10:58 PM
Experimenting with annotation processors - is there an easy in way to figure out whether an annotated property is nullable? The mirror APIs don’t have any information on this. I looked a bit into kotlinx metadata library, but I must be using it in a wrong way as all the flags I’m getting back are nullable … (the flag absolute value is 551). Here’s the code I’m using to gather the flags:
Copy code
val metadataAnnotation = typeElement.getAnnotation(Metadata::class.java)
        val header = KotlinClassHeader(
            metadataAnnotation.kind,
            metadataAnnotation.metadataVersion,
            metadataAnnotation.bytecodeVersion,
            metadataAnnotation.data1,
            metadataAnnotation.data2,
            metadataAnnotation.extraString,
            metadataAnnotation.packageName,
            metadataAnnotation.extraInt
        )

        val metadata = KotlinClassMetadata.read(header)
        when (metadata) {
            is KotlinClassMetadata.Class -> {
                metadata.accept(object: KmClassVisitor()  {
                    override fun visitProperty(
                        flags: Flags,
                        name: String,
                        getterFlags: Flags,
                        setterFlags: Flags
                    ): KmPropertyVisitor? {
                        val nullable = Flag.Type.IS_NULLABLE(flags)
                        Logger.logW("* visiting property $name, flags: $flags, nullable: $nullable")
                        return super.visitProperty(flags, name, getterFlags, setterFlags)
                    }
                })
            }
            else -> {
                Logger.logW("bummer ... not a class: $metadata")
            }
        }
Anyone can see anything?
Also tried to read the metadata annotation at runtime using reflection, but I’m getting the same results. Looks like there is something wrong with the generated metadata in my classes …
s

Shaishav Gandhi

05/28/2019, 11:45 PM
You can check if that property has another annotation with `Nullable`/`NonNull`/`NotNull`. Usually Kotlin non-nulls have the
NotNull
annotation
s

SnowmanX95

05/28/2019, 11:49 PM
Right - that is one possible way, but I was hoping to use the metadata as it can give me additional valuable information
g

gildor

05/29/2019, 2:19 AM
Metdata is the only correct way, not reading nullable annotations
s

Shaishav Gandhi

05/29/2019, 2:43 AM
That's true. Reading nullable annotations is useful when your annotation processor runs on mixed sources.
g

gildor

05/29/2019, 3:25 AM
if it’s on mixed sources it should check is this class has kotlin metadata (it’s Kotlin type) or not (it’s Java)
s

Shaishav Gandhi

05/29/2019, 3:35 AM
What's a nice way to do that? Any code that you can point me to?
g

gildor

05/29/2019, 3:37 AM
not really, you can just check for Kotlin metadata annotation
m

Marc Knaup

05/29/2019, 5:43 AM
s

Shaishav Gandhi

05/29/2019, 5:44 AM
Nice! Will check it out
t

tddmonkey

05/29/2019, 9:37 AM
IIRC inside your
visitProperty
you need to return a
KmPropertyVisitor
and
visitReturnType
. The nullability will be in the
Flags
there
Some code I have that does this, looks like this:
Copy code
override fun visitProperty(flags: Flags, name: String, getterFlags: Flags, setterFlags: Flags): KmPropertyVisitor? {
        return MetadataPropertyVisitor(
            onBuild = { properties.put(it.name, it) },
            name = name,
            outerFlags = flags
        )
Copy code
internal class MetadataPropertyVisitor(
    private val onBuild: (DeclaredProperty) -> Unit,
    private val name: String,
    private val outerFlags: Flags
): KmPropertyVisitor() {
    override fun visitReturnType(flags: Flags): KmTypeVisitor? {
        val property = DeclaredProperty(
            name = name,
            isNullable = Flag.Type.IS_NULLABLE(flags),
            isPrivate = Flag.IS_PRIVATE(outerFlags)
        )
        onBuild(property)
        return super.visitReturnType(flags)
    }
}
(It’s a library that does what I suspect @Marc Knaup has written, but before that existed
m

Marc Knaup

05/29/2019, 12:22 PM
The visitor pattern was way too much boilerplate for me and too complicated, so I wrote a wrapper around it which basically reutbds plenty of easily navigable data glasses.
t

tddmonkey

05/29/2019, 2:44 PM
@Marc Knaup I did the same but never got around to open sourcing it. When I saw you did one I made a note to check it out and see if I can dump mine
😮 1
s

SnowmanX95

05/29/2019, 4:20 PM
Thanks @tddmonkey, this is exactly what I needed. How did you figure this one out? The documentation is not exactly explaining this one ….
t

tddmonkey

05/29/2019, 5:33 PM
Failing tests, the debugger and a lot of patience 😄
Once you get very familiar with the AST it’s not too bad
s

SnowmanX95

05/29/2019, 9:07 PM
Nice. Thanks for taking the one for the team 🙂
😀 1
10 Views