Hi all. Please tell me the right direction to go.....
# arrow-meta
g
Hi all. Please tell me the right direction to go... I try to create a kotlin compiler plugin which should automatically add "@kotlinx.serializable.Serializable" annotation to specific classes BEFORE the kotlinx-serialization plugin will process them. I tried it without arrow meta as pure kotlin compiler plugin using "DelegatingClassBuilder/defineClass" but it seems it's too late in the build process, because no serializers are generated for the classes by the the kotlinx plugin although the annotations are definitely present in the generated class files. So what would be the right way to do/try it using arrow-meta?
r
Hi @Gamadril for this you would need to use
classDeclaration
or similar in meta’s in the quote system. Unfortunately that part will be removed when FIR and a compiler plugin api becomes stable since it depends on the KtElements and descriptors API. If you use that you would intercept all class declarations and replace them for versions that include the annotations. Something along the lines of:
Copy code
val Meta.autoSerialize: CliPlugin get() =
  "AutoSerialize" {
    meta(
      classDeclaration(this, { element.isNotSerializableOrWhateverElseyouWanttoCheck() }) { (c, _) -> 
        Transform.replace(
          replacing = c,
          newDeclaration = """|@kotlinx.serializable.Serializable
                              |$c
                              |""".class(descriptor)
        )
      }
    )
  }
Whatever approach that mutates the declarations in place is not recommended as it would interfere with reported line numbers and even if you add the annotations during analysis like this most likely you will run into issues with the Kotlin IDE plugin not recognising how you are mutating those declarations. This is one of the biggest issues with authoring compiler plugins in general that in Kotlin is yet to be solved. Jebtrains compiler plugins include support in the Kotlin IDEA plugin but community plugins don’t and user experience is always worse than with Jetbrains plugins.
g
Thanks for the quick response. I tried your code in the arrow-meta-examples:
Copy code
val Meta.patchSerializable: CliPlugin
    get() = "Patch classes" {
        meta(
            classDeclaration(this, { element.name == "NewMultipleSource" }) { (c, descriptor) ->
                Transform.replace(
                    replacing = c,
                    newDeclaration = """|@kotlinx.serializable.Serializable
                              |$c
                              |""".class(descriptor)
                )
            }
        )
    }
but .class(descriptor) does not compile. "``class``.syntheticScope" (seen somewhere else without really knowing how it works...) compiles, but use-plugin project throws an error on build step