diff --git a/generator/src/main/kotlin/sh/christian/ozone/api/generator/LexiconClassFileCreator.kt b/generator/src/main/kotlin/sh/christian/ozone/api/generator/LexiconClassFileCreator.kt index 7b9447b..45c3532 100644 --- a/generator/src/main/kotlin/sh/christian/ozone/api/generator/LexiconClassFileCreator.kt +++ b/generator/src/main/kotlin/sh/christian/ozone/api/generator/LexiconClassFileCreator.kt @@ -10,6 +10,8 @@ import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy import com.squareup.kotlinpoet.TypeVariableName import com.squareup.kotlinpoet.withIndent import org.gradle.configurationcache.extensions.capitalized +import sh.christian.ozone.api.generator.builder.EnumClass +import sh.christian.ozone.api.generator.builder.EnumEntry import sh.christian.ozone.api.generator.builder.GeneratorContext import sh.christian.ozone.api.generator.builder.LexiconDataClassesGenerator import sh.christian.ozone.api.generator.builder.SealedRelationship @@ -31,7 +33,7 @@ class LexiconClassFileCreator( private val sealedRelationships = mutableListOf() fun createClassForLexicon(document: LexiconDocument) { - val enums = mutableMapOf>() + val enums = mutableMapOf>() document.defs.forEach { (defKey, defValue) -> val definitionName = if (defKey == "main") "" else defKey diff --git a/generator/src/main/kotlin/sh/christian/ozone/api/generator/builder/GeneratorContext.kt b/generator/src/main/kotlin/sh/christian/ozone/api/generator/builder/GeneratorContext.kt index 8bfd236..471b3c5 100644 --- a/generator/src/main/kotlin/sh/christian/ozone/api/generator/builder/GeneratorContext.kt +++ b/generator/src/main/kotlin/sh/christian/ozone/api/generator/builder/GeneratorContext.kt @@ -21,16 +21,19 @@ private constructor( val procedureName: String = document.id.substringAfterLast('.').removePrefix("defs") val classPrefix: String = prefixOverride ?: procedureName.capitalized() - private val enums = mutableMapOf>() + private val enums = mutableMapOf>() private val types = mutableMapOf() private val typeAliases = mutableMapOf() private val sealedRelationships = mutableListOf() fun addEnum( className: ClassName, + classDescription: String? = null, enumName: String, + enumDescription: String? = null, ) { - enums.getOrPut(className) { mutableSetOf() } += enumName + enums.getOrPut(EnumClass(className, classDescription)) { mutableSetOf() } += + EnumEntry(enumName, enumDescription) } fun addType(typeSpec: TypeSpec) { @@ -57,7 +60,7 @@ private constructor( ) } - fun enums(): Map> { + fun enums(): Map> { return enums.mapValues { it.value.toSet() } } diff --git a/generator/src/main/kotlin/sh/christian/ozone/api/generator/builder/LexiconDataClassesGenerator.kt b/generator/src/main/kotlin/sh/christian/ozone/api/generator/builder/LexiconDataClassesGenerator.kt index 314d890..86182c0 100644 --- a/generator/src/main/kotlin/sh/christian/ozone/api/generator/builder/LexiconDataClassesGenerator.kt +++ b/generator/src/main/kotlin/sh/christian/ozone/api/generator/builder/LexiconDataClassesGenerator.kt @@ -176,7 +176,7 @@ class LexiconDataClassesGenerator( val className = ClassName(context.authority, simpleClassName) primitive.knownValues.forEach { enum -> - context.addEnum(className, enum) + context.addEnum(className, primitive.description, enum, null) } return className } @@ -194,7 +194,7 @@ class LexiconDataClassesGenerator( ) { val className = ClassName(context.authority, context.classPrefix + "Token") val enumName = context.document.id + "#" + context.definitionName - context.addEnum(className, enumName) + context.addEnum(className, null, enumName, token.description) } private fun generateTypes( diff --git a/generator/src/main/kotlin/sh/christian/ozone/api/generator/builder/enums.kt b/generator/src/main/kotlin/sh/christian/ozone/api/generator/builder/enums.kt new file mode 100644 index 0000000..3aa4161 --- /dev/null +++ b/generator/src/main/kotlin/sh/christian/ozone/api/generator/builder/enums.kt @@ -0,0 +1,13 @@ +package sh.christian.ozone.api.generator.builder + +import com.squareup.kotlinpoet.ClassName + +data class EnumClass( + val className: ClassName, + val description: String?, +) + +data class EnumEntry( + val name: String, + val description: String?, +) diff --git a/generator/src/main/kotlin/sh/christian/ozone/api/generator/builder/util.kt b/generator/src/main/kotlin/sh/christian/ozone/api/generator/builder/util.kt index dda56b1..d5b024b 100644 --- a/generator/src/main/kotlin/sh/christian/ozone/api/generator/builder/util.kt +++ b/generator/src/main/kotlin/sh/christian/ozone/api/generator/builder/util.kt @@ -217,21 +217,18 @@ fun createObjectClass( } fun createOpenEnumClass( - className: ClassName, - values: Collection, + enumClass: EnumClass, + entries: Collection, ): List { + val className = enumClass.className val serializerClassName = className.peerClass(className.simpleName + "Serializer") val serializerTypeSpec = TypeSpec.classBuilder(serializerClassName) .addSuperinterface( TypeNames.KSerializer.parameterizedBy(className), - CodeBlock.of("♢%M(%T::safeValueOf)".trimIndent(), stringEnumSerializer, className) + CodeBlock.of("%M(%T::safeValueOf)".trimIndent(), stringEnumSerializer, className) ) .build() - val formattedNames = values.associateWith { value -> - value.substringAfterLast('#').toPascalCase() - } - val sealedClass = TypeSpec.classBuilder(className) .addModifiers(KModifier.SEALED) .addAnnotation( @@ -239,6 +236,7 @@ fun createOpenEnumClass( .addMember("with = %T::class", serializerClassName) .build() ) + .addDescription(enumClass.description) .superclass(TypeNames.AtpEnum) .primaryConstructor( FunSpec.constructorBuilder() @@ -254,20 +252,23 @@ fun createOpenEnumClass( val safeValueOfControlFlow = CodeBlock.builder() .beginControlFlow("return when (value)") - formattedNames.forEach { (value, formatted) -> - safeValueOfControlFlow.addStatement("%S -> %L", value, formatted) + entries.forEach { entry -> + val entryClassName = entry.name.substringAfterLast('#').toPascalCase() + + safeValueOfControlFlow.addStatement("%S -> %L", entry.name, entryClassName) sealedClass.addType( - TypeSpec.objectBuilder(formatted) + TypeSpec.objectBuilder(entryClassName) .addModifiers(KModifier.DATA) + .addDescription(entry.description) .superclass(className) - .addSuperclassConstructorParameter("%S", value) + .addSuperclassConstructorParameter("%S", entry.name) .build() ) } // Avoid conflicting names by appending _ to the unknown name val safeUnknownEntryName = "Unknown".let { - if (it in formattedNames.values) "_$it" else it + if (it in sealedClass.typeSpecs.map { type -> type.name }) "_$it" else it } sealedClass.addType(