Skip to content

Commit

Permalink
Share code between serializers
Browse files Browse the repository at this point in the history
  • Loading branch information
lukellmann committed Aug 24, 2023
1 parent 09ede26 commit b571bbd
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ internal fun BitFlags.generateFileSpec(originatingFile: KSFile) = fileSpecForGen
addKdoc("The raw $valueName used by Discord.")
getter {
when (valueType) {
INT -> addStatement("return 1 shl shift")
INT -> addStatement("return 1·shl·shift")
BIT_SET -> addStatement("return %M().also·{·it[shift]·=·true·}", EMPTY_BIT_SET)
}
}
Expand Down
18 changes: 4 additions & 14 deletions ksp-processors/src/main/kotlin/generation/bitflags/Serializer.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.kord.ksp.generation.bitflags

import com.squareup.kotlinpoet.KModifier.*
import com.squareup.kotlinpoet.KModifier.OVERRIDE
import com.squareup.kotlinpoet.KModifier.PRIVATE
import com.squareup.kotlinpoet.MemberName
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
import com.squareup.kotlinpoet.TypeSpec
Expand All @@ -13,26 +14,15 @@ import dev.kord.ksp.generation.GenerationEntity.BitFlags.ValueType.BIT_SET
import dev.kord.ksp.generation.GenerationEntity.BitFlags.ValueType.INT
import dev.kord.ksp.generation.shared.GenerationContext
import dev.kord.ksp.generation.shared.K_SERIALIZER
import dev.kord.ksp.generation.shared.PRIMITIVE_SERIAL_DESCRIPTOR
import dev.kord.ksp.generation.shared.toPrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
import dev.kord.ksp.generation.shared.addSharedSerializerContent
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder

private val SERIALIZER_METHOD = MemberName("kotlinx.serialization.builtins", "serializer")

context(BitFlags, GenerationContext)
internal fun TypeSpec.Builder.addSerializer() = addObject("Serializer") {
addModifiers(INTERNAL)
addSuperinterface(K_SERIALIZER.parameterizedBy(collectionCN))
addProperty<SerialDescriptor>("descriptor", OVERRIDE) {
initializer(
"%M(%S, %T)",
PRIMITIVE_SERIAL_DESCRIPTOR,
collectionCN.canonicalName,
valueType.toPrimitiveKind(),
)
}
addSharedSerializerContent(collectionCN)
addProperty("delegate", K_SERIALIZER.parameterizedBy(valueCN), PRIVATE) {
when (valueType) {
INT -> initializer("%T.%M()", valueCN, SERIALIZER_METHOD)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,11 @@ package dev.kord.ksp.generation.kordenum

import com.google.devtools.ksp.symbol.KSFile
import com.squareup.kotlinpoet.KModifier.*
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
import com.squareup.kotlinpoet.ksp.addOriginatingKSFile
import dev.kord.ksp.*
import dev.kord.ksp.generation.GenerationEntity.KordEnum
import dev.kord.ksp.generation.GenerationEntity.KordEnum.ValueType
import dev.kord.ksp.generation.GenerationEntity.KordEnum.ValueType.INT
import dev.kord.ksp.generation.GenerationEntity.KordEnum.ValueType.STRING
import dev.kord.ksp.generation.shared.*
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder

private fun ValueType.toEncodingPostfix() = when (this) {
INT -> "Int"
STRING -> "String"
}

internal fun KordEnum.generateFileSpec(originatingFile: KSFile) = fileSpecForGenerationEntity(originatingFile) {
addClass(entityCN) {
Expand Down Expand Up @@ -50,36 +38,7 @@ internal fun KordEnum.generateFileSpec(originatingFile: KSFile) = fileSpecForGen
addSuperclassConstructorParameter(valueName)
}
addEntityEntries()
addObject("Serializer") {
addModifiers(INTERNAL)
addSuperinterface(K_SERIALIZER.parameterizedBy(entityCN))
addProperty<SerialDescriptor>("descriptor", OVERRIDE) {
initializer(
"%M(%S, %T)",
PRIMITIVE_SERIAL_DESCRIPTOR,
entityCN.canonicalName,
valueType.toPrimitiveKind(),
)
}
val encodingPostfix = valueType.toEncodingPostfix()
addFunction("serialize") {
addModifiers(OVERRIDE)
addParameter<Encoder>("encoder")
addParameter("value", entityCN)
addStatement("encoder.encode$encodingPostfix(value.$valueName)")
}
addFunction("deserialize") {
addModifiers(OVERRIDE)
returns(entityCN)
addParameter<Decoder>("decoder")
withControlFlow("return when·(val·$valueName·=·decoder.decode$encodingPostfix())") {
for (entry in entriesDistinctByValue) {
addStatement("$valueFormat·->·${entry.nameWithSuppressedDeprecation}", entry.value)
}
addStatement("else·->·Unknown($valueName)")
}
}
}
addSerializer()
addCompanionObject {
addSharedCompanionObjectContent()
}
Expand Down
45 changes: 45 additions & 0 deletions ksp-processors/src/main/kotlin/generation/kordenum/Serializer.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package dev.kord.ksp.generation.kordenum

import com.squareup.kotlinpoet.KModifier.OVERRIDE
import com.squareup.kotlinpoet.TypeSpec
import dev.kord.ksp.addFunction
import dev.kord.ksp.addObject
import dev.kord.ksp.addParameter
import dev.kord.ksp.generation.GenerationEntity.KordEnum
import dev.kord.ksp.generation.GenerationEntity.KordEnum.ValueType
import dev.kord.ksp.generation.GenerationEntity.KordEnum.ValueType.INT
import dev.kord.ksp.generation.GenerationEntity.KordEnum.ValueType.STRING
import dev.kord.ksp.generation.shared.GenerationContext
import dev.kord.ksp.generation.shared.addSharedSerializerContent
import dev.kord.ksp.generation.shared.nameWithSuppressedDeprecation
import dev.kord.ksp.withControlFlow
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder

private fun ValueType.toEncodingPostfix() = when (this) {
INT -> "Int"
STRING -> "String"
}

context(KordEnum, GenerationContext)
internal fun TypeSpec.Builder.addSerializer() = addObject("Serializer") {
addSharedSerializerContent(entityCN)
val encodingPostfix = valueType.toEncodingPostfix()
addFunction("serialize") {
addModifiers(OVERRIDE)
addParameter<Encoder>("encoder")
addParameter("value", entityCN)
addStatement("encoder.encode$encodingPostfix(value.$valueName)")
}
addFunction("deserialize") {
addModifiers(OVERRIDE)
returns(entityCN)
addParameter<Decoder>("decoder")
withControlFlow("return when·(val·$valueName·=·decoder.decode$encodingPostfix())") {
for (entry in entriesDistinctByValue) {
addStatement("$valueFormat·->·${entry.nameWithSuppressedDeprecation}", entry.value)
}
addStatement("else·->·Unknown($valueName)")
}
}
}
15 changes: 15 additions & 0 deletions ksp-processors/src/main/kotlin/generation/shared/SharedContent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.squareup.kotlinpoet.KModifier.*
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
import dev.kord.ksp.*
import dev.kord.ksp.generation.GenerationEntity
import kotlinx.serialization.descriptors.SerialDescriptor

context(GenerationEntity, GenerationContext)
internal fun TypeSpec.Builder.addEntityKDoc() {
Expand Down Expand Up @@ -40,6 +41,20 @@ internal fun TypeSpec.Builder.addEntityEntries() {
}
}

context(GenerationEntity, GenerationContext)
internal fun TypeSpec.Builder.addSharedSerializerContent(serializedClass: ClassName) {
addModifiers(INTERNAL)
addSuperinterface(K_SERIALIZER.parameterizedBy(serializedClass))
addProperty<SerialDescriptor>("descriptor", OVERRIDE) {
initializer(
"%M(%S, %T)",
PRIMITIVE_SERIAL_DESCRIPTOR,
serializedClass.canonicalName,
valueType.toPrimitiveKind(),
)
}
}

context(GenerationEntity, GenerationContext)
internal fun TypeSpec.Builder.addSharedCompanionObjectContent() {
addModifiers(PUBLIC)
Expand Down

0 comments on commit b571bbd

Please sign in to comment.