pkl icon indicating copy to clipboard operation
pkl copied to clipboard

Implement support for KotlinX Serialization

Open sgammon opened this issue 1 year ago • 1 comments

This change adds support for a new code-gen argument, implementKSerializable, which results in the annotation kotlinx.serialization.Serializable being added to data classes during codegen.

New discussion opened here

Approach

A new argument has been added to the Kotlin code generator and Gradle plugin, at implementKSerializable. When set to true, the code generator annotates data classes with @kotlinx.serialization.Serializable.

If both JVM serialization and KotlinX serialization are enabled, the code generator properly qualifies with java.io.Serializable and import kotlinx.serialization.Serializable. The two are optional and usable independent of each other.

For the moment, this is filed on top of these other PRs to avoid conflicts, since they all touch the code generator; these can be rebased away, though:

  • #194
  • #192

Transitive dependency needs

Users of this code will need to include the KotlinX Serialization compiler plugin in their build, with:

plugins {
  kotlin("plugin.serialization")

  // -- or --
  alias(libs.plugins.kotlin.serialization)  // version catalog

  // -- or --
  id(libs.plugins.kotlin.serialization.get().pluginId)  // multi-module build with version catalog
}

And a dependency on KotlinX Serialization Core, for the annotation, at version 1.5.0 or greater:

dependencies {
  api("org.jetbrains.kotlinx:kotlinx-serialization-core:1.5.0")

  // -- or --
  api(libs.kotlinx.serialization.core)
}
[versions]
# ...
kotlinx-serialization = "1.5.0"  # or greater for newer Kotlin metadata versions
# ...

[libraries]
# ...
kotlinx-serialization = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "kotlinx-serialization" }
# ...

I stopped short of adding an api dependency to Pkl's Kotlin runtime library to avoid adding it to consumer dependency graphs downstream. This could easily be added, though, if preferable. Gradle will generally select the newest available version in a user's build, but builds that don't include KotlinX Serialization already will have to download it if it is added this way, of course.

IDEA and Kotlin warn appropriately if the compiler is not included.

Changelog

  • feat(codegen): add support for kotlin Serializable annotation
  • feat(gradle): add implementKSerializable argument
  • test(codegen): add test for KotlinX serialization support
  • test(codegen): add test for both Java and KotlinX serialization
  • test(gradle): add test for compiling with KotlinX serialization
  • chore: update lockfiles

sgammon avatar Feb 18 '24 22:02 sgammon

Hey @bioball, sorry I missed your review here! I'll take a look. The problem with sealed classes is a bigger issue that may need some design attention before this feature ships.

sgammon avatar Mar 20 '24 22:03 sgammon