Search code examples
javakotlinannotationskaptcode-generation

How to append a method to existing class using annotation processing in java / kotlin?


I'm new to annotation processing and code generation. I want to find out how can I perform such operation like appending new method to existing class. Here is an example of what I want to do:

Assume that we have a class with with custom annotations like this one:

class SourceClass {
    @CustomAnnotation
    fun annotatedFun1(vararg argument: Any) {
        //Do something
    }

    @CustomAnnotation
    fun annotatedFun2(vararg argument: Any) {
        //Do something
    }

    fun someOtherFun() {
        //Do something
    }
}

And the result I want to get - extended copy of that class:

class ResultClass {
    fun hasFunWithName(name: String): Boolean {
        return (name in arrayOf("annotatedFun1", "annotatedFun2"))
    }

    fun callFunByName(name: String, vararg arguments: Any) {
        when (name) {
            "annotatedFun1" -> annotatedFun1(*arguments)
            "annotatedFun2" -> annotatedFun2(*arguments)
        }
    }

    fun annotatedFun1(vararg argument: Any) {
        //Do something
    }

    fun annotatedFun2(vararg argument: Any) {
        //Do something
    }

    fun someOtherFun() {
        //Do something
    }
}

I've already found out how to create annotation processor. I'm looking for a method to save all existing fields, properties and methods in source class and to append a few more methods to it.

If it is possible to modify class without creating new one - it would be perfect, but in all tutorials only new classes are created and I didn't find any example where all contents of source class are being copied to another one.

Please, do not advise to use reflection. I need this for android and so reflection is not the option cause of resources cost. I'm looking for compile-time solution.

It is required for custom script language implemented in app and should be used to simplify wrapper classes structure. When this job is done directly in code - it looks awful when such method count exceeds 20 per class.


Solution

  • Here is a good example of Java Annotation Processing I recently worked with. It's an implementation of @Immutable annotation.

    Check out ByteBuddy or Kotlin Poet to understand how additional code generation works.

    For Kotlin you do almost the same, check this manual for Kotlin-specific steps.