diff --git a/build-logic/convention/src/main/kotlin/com.livefront.sealedenum.kotlin.gradle.kts b/build-logic/convention/src/main/kotlin/com.livefront.sealedenum.kotlin.gradle.kts index b50062df..84326b0f 100644 --- a/build-logic/convention/src/main/kotlin/com.livefront.sealedenum.kotlin.gradle.kts +++ b/build-logic/convention/src/main/kotlin/com.livefront.sealedenum.kotlin.gradle.kts @@ -34,9 +34,10 @@ tasks { withType().configureEach { kotlinOptions { - allWarningsAsErrors = true + // allWarningsAsErrors = true freeCompilerArgs = freeCompilerArgs + "-opt-in=kotlin.RequiresOptIn" jvmTarget = JavaVersion.VERSION_1_8.toString() + languageVersion = "1.9" } } } diff --git a/processing-tests/common/test/kotlin/com/livefront/sealedenum/compilation/basic/TwoDataObjectSealedClass.kt b/processing-tests/common/test/kotlin/com/livefront/sealedenum/compilation/basic/TwoDataObjectSealedClass.kt new file mode 100644 index 00000000..4ff63884 --- /dev/null +++ b/processing-tests/common/test/kotlin/com/livefront/sealedenum/compilation/basic/TwoDataObjectSealedClass.kt @@ -0,0 +1,132 @@ +package com.livefront.sealedenum.compilation.basic + +import com.livefront.sealedenum.GenSealedEnum +import org.intellij.lang.annotations.Language + +sealed class TwoDataObjectSealedClass { + data object FirstObject : TwoDataObjectSealedClass() + + data object SecondObject : TwoDataObjectSealedClass() + + @GenSealedEnum(generateEnum = true) + companion object +} + +@Language("kotlin") +val twoDataObjectSealedClassGenerated = """ +package com.livefront.sealedenum.compilation.basic + +import com.livefront.sealedenum.EnumForSealedEnumProvider +import com.livefront.sealedenum.SealedEnum +import com.livefront.sealedenum.SealedEnumWithEnumProvider +import kotlin.Int +import kotlin.LazyThreadSafetyMode +import kotlin.String +import kotlin.collections.List +import kotlin.reflect.KClass + +/** + * An isomorphic enum for the sealed class [TwoDataObjectSealedClass] + */ +public enum class TwoDataObjectSealedClassEnum() { + TwoDataObjectSealedClass_FirstObject, + TwoDataObjectSealedClass_SecondObject, +} + +/** + * The isomorphic [TwoDataObjectSealedClassEnum] for [this]. + */ +public val TwoDataObjectSealedClass.`enum`: TwoDataObjectSealedClassEnum + get() = TwoDataObjectSealedClassSealedEnum.sealedObjectToEnum(this) + +/** + * The isomorphic [TwoDataObjectSealedClass] for [this]. + */ +public val TwoDataObjectSealedClassEnum.sealedObject: TwoDataObjectSealedClass + get() = TwoDataObjectSealedClassSealedEnum.enumToSealedObject(this) + +/** + * An implementation of [SealedEnum] for the sealed class [TwoDataObjectSealedClass] + */ +public object TwoDataObjectSealedClassSealedEnum : SealedEnum, + SealedEnumWithEnumProvider, + EnumForSealedEnumProvider { + public override val values: List by lazy(mode = + LazyThreadSafetyMode.PUBLICATION) { + listOf( + TwoDataObjectSealedClass.FirstObject, + TwoDataObjectSealedClass.SecondObject + ) + } + + + public override val enumClass: KClass + get() = TwoDataObjectSealedClassEnum::class + + public override fun ordinalOf(obj: TwoDataObjectSealedClass): Int = when (obj) { + is TwoDataObjectSealedClass.FirstObject -> 0 + is TwoDataObjectSealedClass.SecondObject -> 1 + } + + public override fun nameOf(obj: TwoDataObjectSealedClass): String = when (obj) { + is TwoDataObjectSealedClass.FirstObject -> "TwoDataObjectSealedClass_FirstObject" + is TwoDataObjectSealedClass.SecondObject -> "TwoDataObjectSealedClass_SecondObject" + } + + public override fun valueOf(name: String): TwoDataObjectSealedClass = when (name) { + "TwoDataObjectSealedClass_FirstObject" -> TwoDataObjectSealedClass.FirstObject + "TwoDataObjectSealedClass_SecondObject" -> TwoDataObjectSealedClass.SecondObject + else -> throw IllegalArgumentException(""${'"'}No sealed enum constant ${'$'}name""${'"'}) + } + + public override fun sealedObjectToEnum(obj: TwoDataObjectSealedClass): + TwoDataObjectSealedClassEnum = when (obj) { + is TwoDataObjectSealedClass.FirstObject -> + TwoDataObjectSealedClassEnum.TwoDataObjectSealedClass_FirstObject + is TwoDataObjectSealedClass.SecondObject -> + TwoDataObjectSealedClassEnum.TwoDataObjectSealedClass_SecondObject + } + + public override fun enumToSealedObject(`enum`: TwoDataObjectSealedClassEnum): + TwoDataObjectSealedClass = when (enum) { + TwoDataObjectSealedClassEnum.TwoDataObjectSealedClass_FirstObject -> + TwoDataObjectSealedClass.FirstObject + TwoDataObjectSealedClassEnum.TwoDataObjectSealedClass_SecondObject -> + TwoDataObjectSealedClass.SecondObject + } +} + +/** + * The index of [this] in the values list. + */ +public val TwoDataObjectSealedClass.ordinal: Int + get() = TwoDataObjectSealedClassSealedEnum.ordinalOf(this) + +/** + * The name of [this] for use with valueOf. + */ +public val TwoDataObjectSealedClass.name: String + get() = TwoDataObjectSealedClassSealedEnum.nameOf(this) + +/** + * A list of all [TwoDataObjectSealedClass] objects. + */ +public val TwoDataObjectSealedClass.Companion.values: List + get() = TwoDataObjectSealedClassSealedEnum.values + +/** + * Returns an implementation of [SealedEnum] for the sealed class [TwoDataObjectSealedClass] + */ +public val TwoDataObjectSealedClass.Companion.sealedEnum: TwoDataObjectSealedClassSealedEnum + get() = TwoDataObjectSealedClassSealedEnum + +/** + * Returns the [TwoDataObjectSealedClass] object for the given [name]. + * + * If the given name doesn't correspond to any [TwoDataObjectSealedClass], an + * [IllegalArgumentException] will be thrown. + */ +public fun TwoDataObjectSealedClass.Companion.valueOf(name: String): TwoDataObjectSealedClass = + TwoDataObjectSealedClassSealedEnum.valueOf(name) + +""".trimIndent() diff --git a/processing-tests/common/test/kotlin/com/livefront/sealedenum/compilation/basic/TwoDataObjectSealedClassTests.kt b/processing-tests/common/test/kotlin/com/livefront/sealedenum/compilation/basic/TwoDataObjectSealedClassTests.kt new file mode 100644 index 00000000..f68c8891 --- /dev/null +++ b/processing-tests/common/test/kotlin/com/livefront/sealedenum/compilation/basic/TwoDataObjectSealedClassTests.kt @@ -0,0 +1,54 @@ +package com.livefront.sealedenum.compilation.basic + +import com.livefront.sealedenum.testing.assertCompiles +import com.livefront.sealedenum.testing.assertGeneratedFileMatches +import com.livefront.sealedenum.testing.compile +import com.livefront.sealedenum.testing.getCommonSourceFile +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test + +class TwoDataObjectSealedClassTests { + @Test + fun `two data objects sealed class`() { + assertEquals( + listOf(TwoDataObjectSealedClass.FirstObject, TwoDataObjectSealedClass.SecondObject), + TwoDataObjectSealedClassSealedEnum.values + ) + } + + @Test + fun `two enums for sealed class`() { + assertEquals( + listOf( + TwoDataObjectSealedClassEnum.TwoDataObjectSealedClass_FirstObject, + TwoDataObjectSealedClassEnum.TwoDataObjectSealedClass_SecondObject + ), + enumValues().toList() + ) + } + + @Test + fun `two enums for sealed class with mapping`() { + assertEquals( + TwoDataObjectSealedClass.values.map(TwoDataObjectSealedClass::enum), + enumValues().toList() + ) + } + + @Test + fun `correct enum class`() { + assertEquals(TwoDataObjectSealedClassEnum::class, TwoDataObjectSealedClassSealedEnum.enumClass) + } + + @Test + fun `compilation generates correct code`() { + val result = compile(getCommonSourceFile("compilation", "basic", "TwoDataObjectSealedClass.kt")) + + assertCompiles(result) + assertGeneratedFileMatches( + "TwoDataObjectSealedClass_SealedEnum.kt", + twoDataObjectSealedClassGenerated, + result + ) + } +} diff --git a/processing-tests/ksp-tests/src/test/kotlin/com/livefront/sealedenum/testing/Compilation.kt b/processing-tests/ksp-tests/src/test/kotlin/com/livefront/sealedenum/testing/Compilation.kt index cfb4d917..4ab7675e 100644 --- a/processing-tests/ksp-tests/src/test/kotlin/com/livefront/sealedenum/testing/Compilation.kt +++ b/processing-tests/ksp-tests/src/test/kotlin/com/livefront/sealedenum/testing/Compilation.kt @@ -13,4 +13,5 @@ internal fun compile(vararg sourceFiles: SourceFile): KotlinCompilation.Result = sources = sourceFiles.toList() symbolProcessorProviders = listOf(SealedEnumProcessorProvider()) inheritClassPath = true + kotlincArguments = listOf("-language-version", "1.9") }.compile() diff --git a/processing-tests/processor-tests/src/test/kotlin/com/livefront/sealedenum/testing/Compilation.kt b/processing-tests/processor-tests/src/test/kotlin/com/livefront/sealedenum/testing/Compilation.kt index 8460cb08..5e98d5dc 100644 --- a/processing-tests/processor-tests/src/test/kotlin/com/livefront/sealedenum/testing/Compilation.kt +++ b/processing-tests/processor-tests/src/test/kotlin/com/livefront/sealedenum/testing/Compilation.kt @@ -12,5 +12,5 @@ internal fun compile(vararg sourceFiles: SourceFile): KotlinCompilation.Result = sources = sourceFiles.toList() annotationProcessors = listOf(SealedEnumProcessor()) inheritClassPath = true - kotlincArguments = listOf("-language-version", "1.5") + kotlincArguments = listOf("-language-version", "1.9") }.compile()