Generate a new data class using compiler plugin

Inspired by “Writing Your Second Kotlin Compiler Plugin” I have set up my own compiler plugin. So far, I’m able to capture an annotated data class, collect its annotated fields and build fresh new simplified data class (with less fields and without some native methods like component1…N). These simplified data classes are created manually and make an abstraction over transport layer (currently grpc), where it is not suitable to transport the original data class with all its fields.

I’m using multi module gradle project. Let simplify, with modules X,Y,Z, where a module “X” uses the compiler plugin, while modules “Y”, “Z” depend on the “X”.

I can access the new data class using the “class-loader” (module X,Y,Z), I can invoke its constructor to create new instance (module X,Y,Z), but I’m not able to get the class be visible for compile time, IDE navigation, … for an ordinary usage in depending modules (module Y,Z).

The plugin is based on “IrGenerationExtension.generate(…)” where:

  • transformation is started via “IrModuleFragment.transform(IrCompiler(),…)”
    • new IrClasses are added within IrCompiler.visitPackageFragment as IrPackageFragment.addChild
    • new IrFiles are added within IrGenerationExtension.generate as IrModuleFragment.files.add

In the build output files for the new classes are missing, but not sure this is necessary.
Not sure the IrFile is created properly or some step is still missing (like a write the content of the file somehow) or the parent-child hierarchy is wrong, …

val newIrFile = IrFileImpl(
NaiveSourceBasedFileEntryImpl(newClass.name.identifier + “.kt”),
IrFileSymbolImpl(),
newClass.fqNameForIrSerialization
)

Is there a way to get the generated class visible and accessible as any other classes defined in the code, or it is no way ( for now )?.
Is there any tooling that could make the creation of data classes smoother ( available / planned )?

1 Like

I know it doesn’t answer your question and it’s probably too late for such suggestions, but if you only generate new classes and not modify the existing code and if you don’t need some weird bytecode hacks then you could look at Kotlin Symbol Processing API. It’s like good old annotation processors in Java, but on steroids.

Generating of data classes is just a begging, the target is to generate extension functions and completely integrate new parts of the model into code base automatically via the compiler plugin, and most probably we will not be able to avoid code modification.

Definitely I’m aware of KSP and will check it.

Still the information whether it is possible make the generated class generally available is important for further decisions how to proceed, while the current sort of reverse engineering to get generating working is very time demanding.