Generate a field for class using kapt


#1

Does kapt support changing existing classes? If no, is it planned?

Eg. using kapt how to transform this:

package org.kotlin.test

import org.kotlin.annotationProcessor.TestAnnotation

@TestAnnotation
class SimpleClass {
    val ololo = "some value"
}

to this:

package org.kotlin.test

class SimpleClass {
    val ololo = "some value"
    val generatedFileld = "another value"
}

By the way, the example in kotlin-code-generation can generate an extension property:

package test.generated

import org.kotlin.test.SimpleClass

val SimpleClass.simpleClassName
    get() = this::class.java.simpleName

but this is not what I need because extension properties do not have a backing field.


#2

As far as I know it is not possible to change existing classes. But what you can do is create a new class which is identical to the class you want to change and add the fields you want. If you don’t mind the class to be open you can just inherit from the class you want to change.
Than in your code you just use the generated class instead. I know it is not the cleanest solution, but as far as I know it is the only one.

I think there is a java library using code generation which does change classes directly using some kind of hack, so maybe it is also possible to do this in Kotlin. Sadly I can’t remember the name of it.


#3

Unfortunately, inheritance is not suitable for me, as I want to refer the generated field from the original class. But then the class should be abstract and have a generated implementation.

Do you refer to lombok?
They do have a nice example for @Log


#4

Yes, I was thinking about lombok. I guess you want something like the @Data or @Log annotation.

About the inheritance, I was thinking about something like this.

Your file:

package your.package.generation

import org.kotlin.annotationProcessor.TestAnnotation

@TestAnnotation
internal open class SimpleClass {
    val ololo = "some value"
}

will generate:

package your.package

class SimpleClass : your.package.generation.SimpleClass() {
    val ololo = "some value"
    val generatedFileld = "another value"
}

The only thing you would need to add manually would be all the constructors in case SimpleClass is inheriting from a different class and needs to call the super constructor.

When using SimpleClass you would always use the generated version. You can just pretend that your handwritten file does not exist.

Another thing to note: SimpleClass would still be final. If you want it to be open, you could pass as an argument to the annotation.