Hi everybody! I am trying to modify annotations of...
# compiler
s
Hi everybody! I am trying to modify annotations of a property getter. The idea is that I add a new annotation to a property if conditions match. I am overriding
IrElementTransformerVoidWithContext.visitPropertyNew()
and my code looks somewhat like this:
Copy code
override fun visitPropertyNew(declaration: IrProperty): IrStatement {
    declaration.getter?.let {
        it.annotations = it.annotations + aNewAnnotationEntry
    }
    return super.visitPropertyNew(declaration)
}
Problem: This works well for all properties but not for properties of data classes. Question: How do I add an annotation to a getter of a property of a data class declared in its constructor?
👀 2
Ok, it seems like I have to do that in the
visitConstructor
function. Bot how do I access getters and setters from here?
Copy code
override fun visitConstructor(declaration: IrConstructor): IrStatement {
    declaration.valueParameters.forEach { param ->
        // how to access getters/setters from here?
    }
    return super.visitConstructor(declaration)
}
r
The properties won't be under the constructor, just the parameters. If you're trying to annotate the properties, using the value parameters won't work. I'm not sure why your first example doesn't work, unless the data class properties don't have getters, which is possible I suppose. Maybe try dumping the IR (
IrElement.dump(true)
)? You can debug it too, and manually inspect each property.
s
Thank you @rnett.
unless the data class properties don't have getters
My data class looks like this:
Copy code
data class User(@SampleAnnotation val name: String)
Maybe try dumping the IR (
IrElement.dump(true)
)?  You can debug it too, and manually inspect each property.
I am dumping as well as debugging 🙂
r
Can you share the dump? Because I would think that would work
Also, you could try adding the annotation to your code (i.e.
data class User(@get:SampleAnnotation val name: String)
) and see what the IR dump looks like
s
Ok, It didn't work because annotations of constructor properties are not present in properties in
visitPropertyNew
. I can use use-site targets, but it is not suitable in my case. In a nutshell, I want to achieve an effect that if a property declared in constructor or whenever else has an annotation (without specifing use-site target) I want to modify its getter. So now I need to figure out, how to check if a property was produced from a constructor parameter of a data class... Thank you for help @rnett!
r
You mean the annotations like from your example are put on the parameter, not the property? The serialization plugin detects it somehow I think, you might be able to look at that. Or look at the initialization, either on the property's field or in an init block (I'm not sure which is generated)
s
You mean the annotations like from your example are put on the parameter, not the property?
Exactly. My logic was relying on the fact that a property has an annotation. It didn't have, so it didn't enter a needed code block.
The serialization plugin detects it somehow I think
Is this the plugin you are talking about https://github.com/Kotlin/kotlinx.serialization ?
Or look at the initialization, either on the property's field or in an init block (I'm not sure which is generated)
Thank you for the suggestion. I am new to compiler plugins and I do not understand it (yet), but now I know the direction to dig in 🙂
r
Yeah, although the plugin is in the kotlin repo, not the kotlinx.serialization one. What I mean by initialization is you can look through the dumped IR and find the properties. They may have backing fields, which may have initializers that use the value parameter, and you can link them using that. Or they may do the same thing in the init block. I'm trying something similar with serialization annotations and ran into this myself, try making your target annotation (
@SampleAnnotation
in your sample) only target properties (i.e.
@Target(AnnotationTarget.PROPERTY)
). It was required for me to get serializaiton to pick up my @SerialInfo annotation.