Kotlin multi-platform project dynamic source code generation


#1

Hi, I want to learn more about dynamic source code generation in multi-platform projects

background:
when (de)serializing data, one can use hand-written code or better, use reflection
however using reflection comes at a(minimal) performance cost
and the resulting code is harder to debug and reason about
so I decided to use dynamic code generation when I was writing Java:

public void iSerializationTest(){
  NativeBuffer buffer=newBuffer(0x10000);
  new NetdiskFile().serializeInto(buffer);buffer.flip();
  new NetdiskFile().deserializeFrom(buffer); // assert equals
}

as you can see there are no actual implementation but only stubs in the ISerializable interface
however after javac compilation, I write a bytecode decorator based on javassist, which basically:

  1. finds all concrete implementation of ISerializable in the classpath(compiled source)
  2. check if they override related methods, if they have, do nothing and move on to the next class
  3. if not, generate corresponding bytecode for (de)serialization based on their fields

decompiled class file will now look like this(with code auto generated instead of hand-written)

however this approach alone can’t be ported to kotlin multi-platform projects
these data classes as well as generated (de)serialization logic should reside in common module
so they have to be in the source form not compiled(bytecode) ones, and then be compiled by kotlinc

my question being

  1. are there better approaches to my problem? I Googled “Kotlin source generation”, not very useful I think,
    because the generated source can’t be seen by IDE during development, so there may be grammar errors
    and I don’t know how to generate them automatically(Android Studio seems to have related features)
  2. I heard about(but never dig into or actually use) annotation processing both in Java and kotlin, but as they can only generate new source code not modify existing ones, I thought they can’t solve my problem, is it true?

my current direction is:

  1. find a way to write a gradle script to generate corresponding source code
  2. mark the code as “Generated Source” and to try to let IDE recognize them
  3. separate them into a new project so that compilation error won’t stop them from running correctly
  4. automate this process, monitor file change somehow so new sources could be generated automatically

I think there must exist some elegant way to do things like this, consider an example where one want getter and setters to be generated for them automatically. they don’t have to write getter and setters in source code but are allowed to use them during development, the IDE will also recognize the generated code and won’t report grammar errors(non-existent methods)