From ad14f2e0d85840ce93ddde610679cec670549842 Mon Sep 17 00:00:00 2001 From: Jan Galinski Date: Sun, 22 Sep 2024 21:20:36 +0200 Subject: [PATCH] chore: refactor, clean up --- .../test/kotlin/DelegateStringListITest.kt | 15 +++++---- .../test/kotlin/DelegateStringLongMapITest.kt | 14 ++++----- .../src/test/kotlin/DummyExceptionITest.kt | 26 +++++----------- .../src/test/kotlin/HelloWorldExampleITest.kt | 8 ++--- .../test/kotlin/KotlinDataClassSpecITest.kt | 12 +++---- .../kotlin/MyCustomAnnotationSpecITest.kt | 5 ++- .../support/GeneratedAnnotationITest.kt | 8 ++--- _itest/spi-itest/src/test/kotlin/SpiITest.kt | 10 +++--- kotlin-code-generation-test/pom.xml | 6 +--- .../main/kotlin/KotlinCodeGenerationTest.kt | 23 +++++++++++++- .../main/kotlin/KotlinCompilationAssert.kt | 6 ++++ .../src/main/kotlin/_reflection.kt | 31 +++++++++++++++++++ .../kotlin/model/KotlinCompilationCommand.kt | 8 +++-- .../kotlin/model/KotlinCompilationError.kt | 4 +-- .../kotlin/model/KotlinCompilationResult.kt | 26 +++++++++++----- .../src/main/kotlin/KotlinCodeGeneration.kt | 6 +++- .../KotlinAnnotationClassSpecBuilder.kt | 4 +-- .../builder/KotlinAnnotationSpecBuilder.kt | 4 +-- .../KotlinAnonymousClassSpecBuilder.kt | 4 +-- .../kotlin/builder/KotlinClassSpecBuilder.kt | 6 ++-- .../KotlinCompanionObjectSpecBuilder.kt | 4 +-- .../KotlinConstructorPropertySpecBuilder.kt | 5 ++- .../builder/KotlinDataClassSpecBuilder.kt | 4 +-- .../builder/KotlinEnumClassSpecBuilder.kt | 4 +-- .../kotlin/builder/KotlinFileSpecBuilder.kt | 4 +-- .../kotlin/builder/KotlinFunSpecBuilder.kt | 4 +-- .../builder/KotlinInterfaceSpecBuilder.kt | 4 +-- .../kotlin/builder/KotlinObjectSpecBuilder.kt | 4 +-- .../builder/KotlinParameterSpecBuilder.kt | 4 +-- .../builder/KotlinPropertySpecBuilder.kt | 4 +-- .../builder/KotlinTypeAliasSpecBuilder.kt | 4 +-- .../builder/KotlinValueClassSpecBuilder.kt | 4 +-- .../src/main/kotlin/spec/KotlinFileSpec.kt | 2 +- .../main/kotlin/support/ThrowsAnnotation.kt | 14 +++++++++ pom.xml | 4 +-- 35 files changed, 180 insertions(+), 115 deletions(-) create mode 100644 kotlin-code-generation-test/src/main/kotlin/_reflection.kt diff --git a/_itest/builder-itest/src/test/kotlin/DelegateStringListITest.kt b/_itest/builder-itest/src/test/kotlin/DelegateStringListITest.kt index 8375d68..310776d 100644 --- a/_itest/builder-itest/src/test/kotlin/DelegateStringListITest.kt +++ b/_itest/builder-itest/src/test/kotlin/DelegateStringListITest.kt @@ -5,13 +5,13 @@ import com.tschuchort.compiletesting.KotlinCompilation import io.toolisticon.kotlin.generation.KotlinCodeGeneration import io.toolisticon.kotlin.generation.itest.KotlinCodeGenerationITestConfig.ROOT_PACKAGE import io.toolisticon.kotlin.generation.spec.toFileSpec -import io.toolisticon.kotlin.generation.test.KotlinCodeGenerationTest -import io.toolisticon.kotlin.generation.test.model.KotlinCompilationCommand +import io.toolisticon.kotlin.generation.test.KotlinCodeGenerationTest.compile +import io.toolisticon.kotlin.generation.test.callPrimaryConstructor +import io.toolisticon.kotlin.generation.test.model.requireOk import org.assertj.core.api.Assertions.assertThat import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi import org.junit.jupiter.api.Test import kotlin.reflect.KClass -import kotlin.reflect.full.primaryConstructor import io.toolisticon.kotlin.generation.test.KotlinCodeGenerationTest.assertThat as compileAssertThat @Suppress("UNCHECKED_CAST") @@ -20,21 +20,20 @@ internal class DelegateStringListITest { @Test fun `create and use string list`() { - val list = KotlinCodeGeneration.buildDelegateListValueClass(ROOT_PACKAGE, "StringList", String::class) { + val listSpec = KotlinCodeGeneration.buildDelegateListValueClass(ROOT_PACKAGE, "StringList", String::class) { propertyName("list") }.toFileSpec() - val result = KotlinCodeGenerationTest.compile(KotlinCompilationCommand(list)) - + val result = compile(listSpec).requireOk() compileAssertThat(result).errorMessages().isEmpty() compileAssertThat(result).hasExitCode(KotlinCompilation.ExitCode.OK) - val klass: KClass = result.loadClass(list.className) + val klass: KClass = result.loadClass(listSpec.className) val values = listOf("a", "b", "c") - val instance: List = klass.primaryConstructor!!.call(values) as List + val instance: List = klass.callPrimaryConstructor(values) assertThat(instance).hasToString("StringList(list=[a, b, c])") } diff --git a/_itest/builder-itest/src/test/kotlin/DelegateStringLongMapITest.kt b/_itest/builder-itest/src/test/kotlin/DelegateStringLongMapITest.kt index cc732a1..0da87ac 100644 --- a/_itest/builder-itest/src/test/kotlin/DelegateStringLongMapITest.kt +++ b/_itest/builder-itest/src/test/kotlin/DelegateStringLongMapITest.kt @@ -6,13 +6,13 @@ import com.tschuchort.compiletesting.KotlinCompilation import io.toolisticon.kotlin.generation.KotlinCodeGeneration import io.toolisticon.kotlin.generation.itest.KotlinCodeGenerationITestConfig.ROOT_PACKAGE import io.toolisticon.kotlin.generation.spec.toFileSpec -import io.toolisticon.kotlin.generation.test.KotlinCodeGenerationTest -import io.toolisticon.kotlin.generation.test.model.KotlinCompilationCommand +import io.toolisticon.kotlin.generation.test.KotlinCodeGenerationTest.compile +import io.toolisticon.kotlin.generation.test.callPrimaryConstructor +import io.toolisticon.kotlin.generation.test.model.requireOk import org.assertj.core.api.Assertions.assertThat import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi import org.junit.jupiter.api.Test import kotlin.reflect.KClass -import kotlin.reflect.full.primaryConstructor import io.toolisticon.kotlin.generation.test.KotlinCodeGenerationTest.assertThat as compileAssertThat @Suppress("UNCHECKED_CAST") @@ -21,7 +21,7 @@ internal class DelegateStringLongMapITest { @Test fun `create and use string long map`() { - val map = KotlinCodeGeneration.buildDelegateMapValueClass( + val mapSpec = KotlinCodeGeneration.buildDelegateMapValueClass( packageName = ROOT_PACKAGE, simpleName = "StringLongMap", valueType = Long::class.asTypeName() @@ -29,15 +29,15 @@ internal class DelegateStringLongMapITest { propertyName("map") }.toFileSpec() - val result = KotlinCodeGenerationTest.compile(KotlinCompilationCommand(map)) + val result = compile(mapSpec).requireOk() compileAssertThat(result).errorMessages().isEmpty() compileAssertThat(result).hasExitCode(KotlinCompilation.ExitCode.OK) - val klass: KClass = result.loadClass(map.className) + val klass: KClass = result.loadClass(mapSpec.className) val values = mapOf("a" to 1, "b" to 2, "c" to 3) - val instance: Map = klass.primaryConstructor!!.call(values) as Map + val instance: Map = klass.callPrimaryConstructor(values) assertThat(instance).hasToString("StringLongMap(map={a=1, b=2, c=3})") } diff --git a/_itest/builder-itest/src/test/kotlin/DummyExceptionITest.kt b/_itest/builder-itest/src/test/kotlin/DummyExceptionITest.kt index 70093a6..eeb3029 100644 --- a/_itest/builder-itest/src/test/kotlin/DummyExceptionITest.kt +++ b/_itest/builder-itest/src/test/kotlin/DummyExceptionITest.kt @@ -1,20 +1,17 @@ package io.toolisticon.kotlin.generation.itest import com.squareup.kotlinpoet.ExperimentalKotlinPoetApi -import com.tschuchort.compiletesting.KotlinCompilation import io.toolisticon.kotlin.generation.KotlinCodeGeneration.buildRuntimeExceptionClass import io.toolisticon.kotlin.generation.itest.KotlinCodeGenerationITestConfig.ROOT_PACKAGE import io.toolisticon.kotlin.generation.spec.toFileSpec -import io.toolisticon.kotlin.generation.test.KotlinCodeGenerationTest -import io.toolisticon.kotlin.generation.test.model.KotlinCompilationCommand +import io.toolisticon.kotlin.generation.test.KotlinCodeGenerationTest.compile +import io.toolisticon.kotlin.generation.test.callPrimaryConstructor +import io.toolisticon.kotlin.generation.test.getFieldValue +import io.toolisticon.kotlin.generation.test.model.requireOk import org.assertj.core.api.Assertions.assertThat import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi import org.junit.jupiter.api.Test import kotlin.reflect.KClass -import kotlin.reflect.KProperty1 -import kotlin.reflect.full.memberProperties -import kotlin.reflect.full.primaryConstructor -import io.toolisticon.kotlin.generation.test.KotlinCodeGenerationTest.assertThat as compileAssertThat @OptIn(ExperimentalKotlinPoetApi::class, ExperimentalCompilerApi::class) internal class DummyExceptionITest { @@ -28,25 +25,16 @@ internal class DummyExceptionITest { includeCause() }.toFileSpec() - - val result = KotlinCodeGenerationTest.compile(KotlinCompilationCommand(exceptionFile)) - - compileAssertThat(result).errorMessages().isEmpty() - compileAssertThat(result).hasExitCode(KotlinCompilation.ExitCode.OK) + val result = compile(exceptionFile).requireOk() val c: KClass = result.loadClass(exceptionFile.className) val cause = IllegalStateException("foo") - val e: RuntimeException = c.primaryConstructor!!.call(true, "false", cause) as RuntimeException + val e: RuntimeException = c.callPrimaryConstructor(true, "false", cause) assertThat(e.localizedMessage).isEqualTo("Dummy exception: expected: true, actual: 'false'.") - // TODO try to get value via pure kotlin without falling back to java - val expectedProperty: KProperty1 = c.memberProperties.single { it.name == "expected" } - val field = c.java.getDeclaredField("expected").apply { isAccessible = true } - - val expectedValue = field.get(e) as Boolean - + val expectedValue: Boolean = e.getFieldValue("expected") assertThat(expectedValue).isTrue() } } diff --git a/_itest/builder-itest/src/test/kotlin/HelloWorldExampleITest.kt b/_itest/builder-itest/src/test/kotlin/HelloWorldExampleITest.kt index b88e1d7..d545206 100644 --- a/_itest/builder-itest/src/test/kotlin/HelloWorldExampleITest.kt +++ b/_itest/builder-itest/src/test/kotlin/HelloWorldExampleITest.kt @@ -1,4 +1,3 @@ - package io.toolisticon.kotlin.generation.itest import com.squareup.kotlinpoet.ClassName @@ -8,7 +7,8 @@ import io.toolisticon.kotlin.generation.KotlinCodeGeneration.buildClass import io.toolisticon.kotlin.generation.KotlinCodeGeneration.buildFile import io.toolisticon.kotlin.generation.KotlinCodeGeneration.buildFun import io.toolisticon.kotlin.generation.test.KotlinCodeGenerationTest -import io.toolisticon.kotlin.generation.test.model.KotlinCompilationCommand +import io.toolisticon.kotlin.generation.test.KotlinCodeGenerationTest.compile +import io.toolisticon.kotlin.generation.test.model.requireOk import org.assertj.core.api.Assertions.assertThat import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi import org.junit.jupiter.api.Test @@ -37,9 +37,7 @@ internal class HelloWorldExampleITest { assertThat(file.packageName).isEqualTo("foo.bar") - val result = KotlinCodeGenerationTest.compile(cmd = KotlinCompilationCommand(fileSpec = file)) - - println(result) + val result = compile(file).requireOk() KotlinCodeGenerationTest.assertThat(result).hasExitCode(KotlinCompilation.ExitCode.OK) } diff --git a/_itest/builder-itest/src/test/kotlin/KotlinDataClassSpecITest.kt b/_itest/builder-itest/src/test/kotlin/KotlinDataClassSpecITest.kt index dd25786..c66a250 100644 --- a/_itest/builder-itest/src/test/kotlin/KotlinDataClassSpecITest.kt +++ b/_itest/builder-itest/src/test/kotlin/KotlinDataClassSpecITest.kt @@ -1,4 +1,3 @@ - package io.toolisticon.kotlin.generation.itest import com.squareup.kotlinpoet.ClassName @@ -7,12 +6,12 @@ import com.squareup.kotlinpoet.asTypeName import com.tschuchort.compiletesting.KotlinCompilation import io.toolisticon.kotlin.generation.KotlinCodeGeneration.buildDataClass import io.toolisticon.kotlin.generation.spec.toFileSpec -import io.toolisticon.kotlin.generation.test.KotlinCodeGenerationTest -import io.toolisticon.kotlin.generation.test.model.KotlinCompilationCommand +import io.toolisticon.kotlin.generation.test.KotlinCodeGenerationTest.compile +import io.toolisticon.kotlin.generation.test.callPrimaryConstructor +import io.toolisticon.kotlin.generation.test.model.requireOk import org.assertj.core.api.Assertions.assertThat import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi import org.junit.jupiter.api.Test -import kotlin.reflect.full.primaryConstructor import io.toolisticon.kotlin.generation.test.KotlinCodeGenerationTest.assertThat as compileAssertThat @OptIn(ExperimentalKotlinPoetApi::class, ExperimentalCompilerApi::class) @@ -29,14 +28,13 @@ internal class KotlinDataClassSpecITest { val file = spec.toFileSpec() - val result = KotlinCodeGenerationTest.compile(KotlinCompilationCommand(file)) + val result = compile(file).requireOk() compileAssertThat(result).errorMessages().isEmpty() compileAssertThat(result).hasExitCode(KotlinCompilation.ExitCode.OK) val klass = result.loadClass(className) - assertThat(klass.primaryConstructor!!.call("hello world", 25)) + assertThat(klass.callPrimaryConstructor("hello world", 25)) .hasToString("Bar(name=hello world, age=25)") } - } diff --git a/_itest/builder-itest/src/test/kotlin/MyCustomAnnotationSpecITest.kt b/_itest/builder-itest/src/test/kotlin/MyCustomAnnotationSpecITest.kt index 2364625..f9fd6cf 100644 --- a/_itest/builder-itest/src/test/kotlin/MyCustomAnnotationSpecITest.kt +++ b/_itest/builder-itest/src/test/kotlin/MyCustomAnnotationSpecITest.kt @@ -1,4 +1,3 @@ - package io.toolisticon.kotlin.generation.itest import com.squareup.kotlinpoet.ClassName @@ -42,8 +41,8 @@ internal class MyCustomAnnotationSpecITest { val klass: KClass = result.loadClass(name) assertThat(klass.asClassName()).isEqualTo(name) - assertThat(klass.annotations).hasSize(1) - val annotation: Annotation = klass.annotations[0] + assertThat(klass.java.annotations).hasSize(2) // 2 because Meta is included + val annotation: Annotation = klass.java.annotations[0] assertThat(annotation).hasToString("@io.toolisticon.kotlin.generation.itest.created.MyCustomAnnotation(\"hello\")") } } diff --git a/_itest/builder-itest/src/test/kotlin/support/GeneratedAnnotationITest.kt b/_itest/builder-itest/src/test/kotlin/support/GeneratedAnnotationITest.kt index ac9929f..85d78ff 100644 --- a/_itest/builder-itest/src/test/kotlin/support/GeneratedAnnotationITest.kt +++ b/_itest/builder-itest/src/test/kotlin/support/GeneratedAnnotationITest.kt @@ -1,11 +1,11 @@ - package io.toolisticon.kotlin.generation.itest.support import com.squareup.kotlinpoet.ExperimentalKotlinPoetApi import io.toolisticon.kotlin.generation.KotlinCodeGeneration.buildDataClass import io.toolisticon.kotlin.generation.spec.toFileSpec import io.toolisticon.kotlin.generation.support.GeneratedAnnotation -import io.toolisticon.kotlin.generation.test.KotlinCodeGenerationTest +import io.toolisticon.kotlin.generation.test.KotlinCodeGenerationTest.assertThat +import io.toolisticon.kotlin.generation.test.KotlinCodeGenerationTest.compile import io.toolisticon.kotlin.generation.test.model.KotlinCompilationCommand import io.toolisticon.kotlin.generation.test.model.KotlinCompilationResult import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi @@ -21,7 +21,7 @@ internal class GeneratedAnnotationITest { addAnnotation(GeneratedAnnotation()) }.toFileSpec() - val result: KotlinCompilationResult = KotlinCodeGenerationTest.compile(cmd = KotlinCompilationCommand(file)) - KotlinCodeGenerationTest.assertThat(result).errorMessages().isEmpty() + val result: KotlinCompilationResult = compile(cmd = KotlinCompilationCommand(file)) + assertThat(result).errorMessages().isEmpty() } } diff --git a/_itest/spi-itest/src/test/kotlin/SpiITest.kt b/_itest/spi-itest/src/test/kotlin/SpiITest.kt index c371675..17f9497 100644 --- a/_itest/spi-itest/src/test/kotlin/SpiITest.kt +++ b/_itest/spi-itest/src/test/kotlin/SpiITest.kt @@ -1,13 +1,14 @@ package io.toolisticon.kotlin.generation.itest.spi import com.squareup.kotlinpoet.ExperimentalKotlinPoetApi -import com.tschuchort.compiletesting.KotlinCompilation import io.toolisticon.kotlin.generation.KotlinCodeGeneration import io.toolisticon.kotlin.generation.KotlinCodeGeneration.className import io.toolisticon.kotlin.generation.KotlinCodeGeneration.spi.registry import io.toolisticon.kotlin.generation.spi.strategy.executeSingle -import io.toolisticon.kotlin.generation.test.KotlinCodeGenerationTest +import io.toolisticon.kotlin.generation.test.KotlinCodeGenerationTest.compile +import io.toolisticon.kotlin.generation.test.callPrimaryConstructor import io.toolisticon.kotlin.generation.test.model.KotlinCompilationCommand +import io.toolisticon.kotlin.generation.test.model.requireOk import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatThrownBy import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi @@ -44,10 +45,9 @@ internal class SpiITest { val spec = requireNotNull(context.registry.strategies.filter(TestDataClassStrategy::class).executeSingle(context, input)) val file = KotlinCodeGeneration.builder.fileBuilder(input.className).addType(spec).build() - val result = KotlinCodeGenerationTest.compile(KotlinCompilationCommand(file)) - KotlinCodeGenerationTest.assertThat(result).hasExitCode(KotlinCompilation.ExitCode.OK) + val result = compile(KotlinCompilationCommand(file)).requireOk() - val foo = result.loadClass(input.className).java.getDeclaredConstructor(String::class.java, Long::class.java).newInstance("Foo", 5L) + val foo: Any = result.loadClass(input.className).callPrimaryConstructor("Foo", 5L) assertThat(foo).hasToString("ExampleDataClass(name=Foo, foo=5)") } diff --git a/kotlin-code-generation-test/pom.xml b/kotlin-code-generation-test/pom.xml index 657ac16..c5c28be 100644 --- a/kotlin-code-generation-test/pom.xml +++ b/kotlin-code-generation-test/pom.xml @@ -1,4 +1,4 @@ - 4.0.0 @@ -41,15 +41,11 @@ org.jetbrains.kotlin kotlin-annotation-processing-embeddable - - ${kotlin.version} org.jetbrains.kotlin kotlin-annotation-processing-compiler - - ${kotlin.version} diff --git a/kotlin-code-generation-test/src/main/kotlin/KotlinCodeGenerationTest.kt b/kotlin-code-generation-test/src/main/kotlin/KotlinCodeGenerationTest.kt index 63f4c60..e1cf023 100644 --- a/kotlin-code-generation-test/src/main/kotlin/KotlinCodeGenerationTest.kt +++ b/kotlin-code-generation-test/src/main/kotlin/KotlinCodeGenerationTest.kt @@ -5,6 +5,7 @@ import com.tschuchort.compiletesting.JvmCompilationResult import com.tschuchort.compiletesting.KotlinCompilation import com.tschuchort.compiletesting.SourceFile import io.toolisticon.kotlin.generation.spec.KotlinFileSpec +import io.toolisticon.kotlin.generation.spec.KotlinFileSpecList import io.toolisticon.kotlin.generation.test.model.KotlinCompilationCommand import io.toolisticon.kotlin.generation.test.model.KotlinCompilationResult import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi @@ -35,12 +36,18 @@ import java.io.ByteArrayOutputStream @ExperimentalKotlinPoetApi object KotlinCodeGenerationTest { + /** + * @see KotlinCompilationAssert + */ fun assertThat(actual: KotlinCompilationResult): KotlinCompilationAssert = KotlinCompilationAssert(actual) + /** + * Compiles files contained in command. + */ fun compile(cmd: KotlinCompilationCommand): KotlinCompilationResult { val result: JvmCompilationResult = KotlinCompilation().apply { - sources = cmd.sourceFiles + sources = cmd.toList() inheritClassPath = true @@ -52,5 +59,19 @@ object KotlinCodeGenerationTest { return KotlinCompilationResult(cmd = cmd, result = result) } + + /** + * Convenience to compile files directly. + * @see [KotlinCodeGenerationTest.compile] + */ + fun compile(vararg fileSpec: KotlinFileSpec) = this.compile( + KotlinCompilationCommand( + KotlinFileSpecList.of(fileSpec.toList()) + ) + ) + + /** + * Extract sourceFile from spec. + */ fun KotlinFileSpec.sourceFile() = SourceFile.kotlin(name = this.fileName, contents = this.code) } diff --git a/kotlin-code-generation-test/src/main/kotlin/KotlinCompilationAssert.kt b/kotlin-code-generation-test/src/main/kotlin/KotlinCompilationAssert.kt index 6dec04a..7b5e7ed 100644 --- a/kotlin-code-generation-test/src/main/kotlin/KotlinCompilationAssert.kt +++ b/kotlin-code-generation-test/src/main/kotlin/KotlinCompilationAssert.kt @@ -17,8 +17,14 @@ class KotlinCompilationAssert( actual: KotlinCompilationResult, ) : AbstractAssert(actual, KotlinCompilationAssert::class.java) { + /** + * Assertions on error messages. + */ fun errorMessages() = Assertions.assertThat(actual.errors) + /** + * Assertion on exitCode. + */ fun hasExitCode(exitCode: KotlinCompilation.ExitCode): KotlinCompilationAssert = apply { Assertions.assertThat(actual.exitCode).isEqualTo(exitCode) } diff --git a/kotlin-code-generation-test/src/main/kotlin/_reflection.kt b/kotlin-code-generation-test/src/main/kotlin/_reflection.kt new file mode 100644 index 0000000..8551ea7 --- /dev/null +++ b/kotlin-code-generation-test/src/main/kotlin/_reflection.kt @@ -0,0 +1,31 @@ +package io.toolisticon.kotlin.generation.test + +import kotlin.reflect.KClass +import kotlin.reflect.full.createInstance +import kotlin.reflect.full.primaryConstructor + + +/** + * Create instance of type `` from [KClass]. + */ +inline fun KClass.callPrimaryConstructor(vararg params: Any): T { + // TODO "call" is not resolvable + return if (params.isEmpty()) { + this.createInstance() + } else { + val pc = requireNotNull(this.primaryConstructor) + pc.call(*params) + } as T +} + +/** + * Get value of type `T` of field. + * + * @param name name of the field + * @return value T + */ +// TODO looking for a pure kotlin reflect solution +inline fun Any.getFieldValue(name: String): T = this::class.java + .getDeclaredField(name) + .apply { isAccessible = true } + .get(this) as T diff --git a/kotlin-code-generation-test/src/main/kotlin/model/KotlinCompilationCommand.kt b/kotlin-code-generation-test/src/main/kotlin/model/KotlinCompilationCommand.kt index 746e988..376a77d 100644 --- a/kotlin-code-generation-test/src/main/kotlin/model/KotlinCompilationCommand.kt +++ b/kotlin-code-generation-test/src/main/kotlin/model/KotlinCompilationCommand.kt @@ -14,11 +14,13 @@ import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi @ExperimentalCompilerApi data class KotlinCompilationCommand( val fileSpecs: KotlinFileSpecList -) { +) : Iterable { - constructor(fileSpec: KotlinFileSpec) : this(KotlinFileSpecList(fileSpec)) + constructor(vararg fileSpecs: KotlinFileSpec) : this(KotlinFileSpecList(*fileSpecs)) operator fun plus(fileSpec: KotlinFileSpec) = copy(fileSpecs = fileSpecs + fileSpec) - val sourceFiles: List by lazy { fileSpecs.map { it.sourceFile() } } + private val sourceFiles: List by lazy { fileSpecs.map { it.sourceFile() } } + + override fun iterator(): Iterator = sourceFiles.iterator() } diff --git a/kotlin-code-generation-test/src/main/kotlin/model/KotlinCompilationError.kt b/kotlin-code-generation-test/src/main/kotlin/model/KotlinCompilationError.kt index 2e9adde..534c1dd 100644 --- a/kotlin-code-generation-test/src/main/kotlin/model/KotlinCompilationError.kt +++ b/kotlin-code-generation-test/src/main/kotlin/model/KotlinCompilationError.kt @@ -6,6 +6,4 @@ package io.toolisticon.kotlin.generation.test.model data class KotlinCompilationError( val message: String, val file: String -) { - override fun toString()= "KotlinCompilationError(message='$message', file='$file')" -} +) diff --git a/kotlin-code-generation-test/src/main/kotlin/model/KotlinCompilationResult.kt b/kotlin-code-generation-test/src/main/kotlin/model/KotlinCompilationResult.kt index 0331d69..2761779 100644 --- a/kotlin-code-generation-test/src/main/kotlin/model/KotlinCompilationResult.kt +++ b/kotlin-code-generation-test/src/main/kotlin/model/KotlinCompilationResult.kt @@ -4,7 +4,7 @@ import com.squareup.kotlinpoet.ClassName import com.squareup.kotlinpoet.ExperimentalKotlinPoetApi import com.tschuchort.compiletesting.JvmCompilationResult import com.tschuchort.compiletesting.KotlinCompilation -import org.assertj.core.api.Assertions.assertThat +import io.toolisticon.kotlin.generation.test.KotlinCodeGenerationTest.assertThat import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi import kotlin.reflect.KClass @@ -18,8 +18,14 @@ data class KotlinCompilationResult( val result: JvmCompilationResult ) { + /** + * OK or ERROR. + */ val exitCode = result.exitCode + /** + * List of errors, one per parsed error line. + */ val errors: List by lazy { result.messages.lines() .filter { it.startsWith("e:") } @@ -43,12 +49,6 @@ data class KotlinCompilationResult( fun loadClass(className: ClassName): KClass = result.classLoader.loadClass(className.canonicalName).kotlin - fun shouldBeOk() { - assertThat(exitCode) - .`as` { "compilation failed with errors: $errors" } - .isEqualTo(KotlinCompilation.ExitCode.OK) - } - override fun toString() = toString(false) fun toString(includeCommand: Boolean) = "${this::class.simpleName}(" + if (includeCommand) { @@ -58,3 +58,15 @@ data class KotlinCompilationResult( } + "exitCode=$exitCode, errors=$errors, generatedSources=$generatedSources)" } + +/** + * Convenience for `assertThat(result).hasExitCode(). + */ +@ExperimentalCompilerApi +@ExperimentalKotlinPoetApi +fun KotlinCompilationResult.requireOk() = apply { + assertThat(this) + .`as` { "compilation failed with errors: ${errors}." } + .hasExitCode(KotlinCompilation.ExitCode.OK) +} + diff --git a/kotlin-code-generation/src/main/kotlin/KotlinCodeGeneration.kt b/kotlin-code-generation/src/main/kotlin/KotlinCodeGeneration.kt index 0d28eb7..e934f28 100644 --- a/kotlin-code-generation/src/main/kotlin/KotlinCodeGeneration.kt +++ b/kotlin-code-generation/src/main/kotlin/KotlinCodeGeneration.kt @@ -43,6 +43,8 @@ import kotlin.reflect.full.isSubclassOf @ExperimentalKotlinPoetApi object KotlinCodeGeneration : KLogging() { + // region [Category: build* functions] + /** * Build a [KotlinAnnotationSpec] using given type and receiver fn. * @see [KotlinAnnotationSpecBuilder.builder] @@ -296,6 +298,8 @@ object KotlinCodeGeneration : KLogging() { inline fun buildValueClass(packageName: PackageName, simpleName: SimpleName, block: KotlinValueClassSpecBuilderReceiver = {}): KotlinValueClassSpec = buildValueClass(className(packageName, simpleName), block) + // endregion [Category: build* functions] + /** * Static access for all builders. */ @@ -573,7 +577,7 @@ object KotlinCodeGeneration : KLogging() { * @throws IllegalStateException when no matching strategy is found. */ inline fun , reified INPUT : Any> generateFiles( - contextFactory: KotlinCodeGenerationContextFactory, + contextFactory: KotlinCodeGenerationContextFactory, input: INPUT ): KotlinFileSpecList = generateFiles(context = contextFactory.invoke(input), input = input) diff --git a/kotlin-code-generation/src/main/kotlin/builder/KotlinAnnotationClassSpecBuilder.kt b/kotlin-code-generation/src/main/kotlin/builder/KotlinAnnotationClassSpecBuilder.kt index 47d1ea3..445b745 100644 --- a/kotlin-code-generation/src/main/kotlin/builder/KotlinAnnotationClassSpecBuilder.kt +++ b/kotlin-code-generation/src/main/kotlin/builder/KotlinAnnotationClassSpecBuilder.kt @@ -96,7 +96,7 @@ class KotlinAnnotationClassSpecBuilder internal constructor( return KotlinAnnotationClassSpec(className = className, spec = delegate.build()) } - // + // region [overrides] override fun addAnnotation(spec: KotlinAnnotationSpecSupplier) = apply { delegate.addAnnotation(spec.get()) } override fun addConstructorProperty(spec: KotlinConstructorPropertySpecSupplier) = apply { constructorProperties[spec.name] = spec } override fun contextReceivers(vararg receiverTypes: TypeName) = builder { this.contextReceivers(*receiverTypes) } @@ -107,7 +107,7 @@ class KotlinAnnotationClassSpecBuilder internal constructor( override fun addType(typeSpec: TypeSpecSupplier) = builder { this.addType(typeSpec.get()) } override fun addTag(type: KClass<*>, tag: Any?) = builder { this.tag(type, tag) } override fun builder(block: TypeSpecBuilderReceiver) = apply { delegate.builder.block() } - // + // endregion [overrides] } @ExperimentalKotlinPoetApi diff --git a/kotlin-code-generation/src/main/kotlin/builder/KotlinAnnotationSpecBuilder.kt b/kotlin-code-generation/src/main/kotlin/builder/KotlinAnnotationSpecBuilder.kt index 2ac80b6..6788bd7 100644 --- a/kotlin-code-generation/src/main/kotlin/builder/KotlinAnnotationSpecBuilder.kt +++ b/kotlin-code-generation/src/main/kotlin/builder/KotlinAnnotationSpecBuilder.kt @@ -159,12 +159,12 @@ class KotlinAnnotationSpecBuilder internal constructor( return KotlinAnnotationSpec(spec = delegate.build()) } - // + // region [overrides] override fun addTag(type: KClass<*>, tag: Any?) = builder { this.tag(type, tag) } override fun builder(block: AnnotationSpecBuilderReceiver) = apply { delegate.builder.block() } override fun get(): AnnotationSpec = build().get() override fun spec(): KotlinAnnotationSpec = build() - // + // endregion [overrides] } @ExperimentalKotlinPoetApi diff --git a/kotlin-code-generation/src/main/kotlin/builder/KotlinAnonymousClassSpecBuilder.kt b/kotlin-code-generation/src/main/kotlin/builder/KotlinAnonymousClassSpecBuilder.kt index 4858d82..4af8612 100644 --- a/kotlin-code-generation/src/main/kotlin/builder/KotlinAnonymousClassSpecBuilder.kt +++ b/kotlin-code-generation/src/main/kotlin/builder/KotlinAnonymousClassSpecBuilder.kt @@ -51,7 +51,7 @@ class KotlinAnonymousClassSpecBuilder internal constructor( override fun build(): KotlinAnonymousClassSpec = KotlinAnonymousClassSpec(delegate.build()) - // + // region [overrides] override fun addAnnotation(spec: KotlinAnnotationSpecSupplier) = apply { delegate.addAnnotation(spec.get()) } override fun contextReceivers(vararg receiverTypes: TypeName) = builder { this.contextReceivers(*receiverTypes) } override fun addFunction(funSpec: KotlinFunSpecSupplier) = apply { delegate.addFunction(funSpec.get()) } @@ -63,7 +63,7 @@ class KotlinAnonymousClassSpecBuilder internal constructor( override fun addType(typeSpec: TypeSpecSupplier) = builder { this.addType(typeSpec.get()) } override fun addTag(type: KClass<*>, tag: Any?) = builder { this.tag(type, tag) } override fun builder(block: TypeSpecBuilderReceiver) = apply { delegate.builder.block() } - // + // endregion [overrides] } @ExperimentalKotlinPoetApi diff --git a/kotlin-code-generation/src/main/kotlin/builder/KotlinClassSpecBuilder.kt b/kotlin-code-generation/src/main/kotlin/builder/KotlinClassSpecBuilder.kt index dc2f057..de16293 100644 --- a/kotlin-code-generation/src/main/kotlin/builder/KotlinClassSpecBuilder.kt +++ b/kotlin-code-generation/src/main/kotlin/builder/KotlinClassSpecBuilder.kt @@ -65,7 +65,7 @@ class KotlinClassSpecBuilder internal constructor( override fun build(): KotlinClassSpec { val hasConstructorProperties = constructorProperties.isNotEmpty() - check( !(hasConstructorProperties && isSetPrimaryConstructor)) { "Decide if you want to use the constructorProperty support OR define a custom primary constructor, not both." } + check(!(hasConstructorProperties && isSetPrimaryConstructor)) { "Decide if you want to use the constructorProperty support OR define a custom primary constructor, not both." } if (hasConstructorProperties) { val constructor = delegate.primaryConstructorWithProperties(toList(constructorProperties.values)) @@ -75,7 +75,7 @@ class KotlinClassSpecBuilder internal constructor( return KotlinClassSpec(className = className, spec = delegate.build()) } - // + // region [overrides] override fun addAnnotation(spec: KotlinAnnotationSpecSupplier) = apply { delegate.addAnnotation(spec.get()) } override fun addConstructorProperty(spec: KotlinConstructorPropertySpecSupplier) = apply { constructorProperties[spec.name] = spec } override fun contextReceivers(vararg receiverTypes: TypeName) = builder { this.contextReceivers(*receiverTypes) } @@ -88,7 +88,7 @@ class KotlinClassSpecBuilder internal constructor( override fun addType(typeSpec: TypeSpecSupplier) = builder { this.addType(typeSpec.get()) } override fun addTag(type: KClass<*>, tag: Any?) = builder { this.tag(type, tag) } override fun builder(block: TypeSpecBuilderReceiver) = apply { delegate.builder.block() } - // + // endregion [overrides] } @ExperimentalKotlinPoetApi diff --git a/kotlin-code-generation/src/main/kotlin/builder/KotlinCompanionObjectSpecBuilder.kt b/kotlin-code-generation/src/main/kotlin/builder/KotlinCompanionObjectSpecBuilder.kt index ca15fe4..825eb8f 100644 --- a/kotlin-code-generation/src/main/kotlin/builder/KotlinCompanionObjectSpecBuilder.kt +++ b/kotlin-code-generation/src/main/kotlin/builder/KotlinCompanionObjectSpecBuilder.kt @@ -53,7 +53,7 @@ class KotlinCompanionObjectSpecBuilder internal constructor( override fun build(): KotlinCompanionObjectSpec = KotlinCompanionObjectSpec(spec = delegate.build()) - // + // region [overrides] override fun addAnnotation(spec: KotlinAnnotationSpecSupplier) = apply { delegate.addAnnotation(spec.get()) } override fun contextReceivers(vararg receiverTypes: TypeName) = builder { delegate.contextReceivers(*receiverTypes) } override fun addFunction(funSpec: KotlinFunSpecSupplier) = apply { delegate.addFunction(funSpec.get()) } @@ -65,7 +65,7 @@ class KotlinCompanionObjectSpecBuilder internal constructor( override fun addType(typeSpec: TypeSpecSupplier) = builder { delegate.addType(typeSpec.get()) } override fun addTag(type: KClass<*>, tag: Any?) = builder { this.tag(type, tag) } override fun builder(block: TypeSpecBuilderReceiver) = apply { delegate.builder.block() } - // + // endregion [overrides] } @ExperimentalKotlinPoetApi diff --git a/kotlin-code-generation/src/main/kotlin/builder/KotlinConstructorPropertySpecBuilder.kt b/kotlin-code-generation/src/main/kotlin/builder/KotlinConstructorPropertySpecBuilder.kt index 6e4a297..a0d257b 100644 --- a/kotlin-code-generation/src/main/kotlin/builder/KotlinConstructorPropertySpecBuilder.kt +++ b/kotlin-code-generation/src/main/kotlin/builder/KotlinConstructorPropertySpecBuilder.kt @@ -6,7 +6,6 @@ import io.toolisticon.kotlin.generation.poet.FunSpecBuilder import io.toolisticon.kotlin.generation.poet.FunSpecBuilder.Companion.wrap import io.toolisticon.kotlin.generation.poet.KDoc import io.toolisticon.kotlin.generation.poet.TypeSpecBuilder -import io.toolisticon.kotlin.generation.poet.TypeSpecSupplier import io.toolisticon.kotlin.generation.spec.* import kotlin.reflect.KClass @@ -57,13 +56,13 @@ class KotlinConstructorPropertySpecBuilder internal constructor( return KotlinConstructorPropertySpec(parameter = parameter, property = property) } - // + // region [overrides] override fun addAnnotation(spec: KotlinAnnotationSpecSupplier) = apply { parameterBuilder.addAnnotation(spec) } override fun addKdoc(kdoc: KDoc) = apply { parameterBuilder.addKdoc(kdoc) } override fun addModifiers(vararg modifiers: KModifier) = apply { propertyBuilder.addModifiers(*modifiers) } override fun addTag(type: KClass<*>, tag: Any?) = apply { propertyBuilder.addTag(type, tag) } override fun spec(): KotlinConstructorPropertySpec = build() - // + // endregion [overrides] } diff --git a/kotlin-code-generation/src/main/kotlin/builder/KotlinDataClassSpecBuilder.kt b/kotlin-code-generation/src/main/kotlin/builder/KotlinDataClassSpecBuilder.kt index 4da498f..046c727 100644 --- a/kotlin-code-generation/src/main/kotlin/builder/KotlinDataClassSpecBuilder.kt +++ b/kotlin-code-generation/src/main/kotlin/builder/KotlinDataClassSpecBuilder.kt @@ -65,7 +65,7 @@ class KotlinDataClassSpecBuilder internal constructor( return KotlinDataClassSpec(className = className, spec = delegate.build()) } - // + // region [overrides] override fun addAnnotation(spec: KotlinAnnotationSpecSupplier) = apply { delegate.addAnnotation(spec.get()) } override fun addConstructorProperty(spec: KotlinConstructorPropertySpecSupplier) = apply { this.constructorProperties[spec.name] = spec } override fun contextReceivers(vararg receiverTypes: TypeName) = builder { this.contextReceivers(*receiverTypes) } @@ -78,7 +78,7 @@ class KotlinDataClassSpecBuilder internal constructor( override fun addType(typeSpec: TypeSpecSupplier) = builder { this.addType(typeSpec.get()) } override fun addTag(type: KClass<*>, tag: Any?) = builder { this.tag(type, tag) } override fun builder(block: TypeSpecBuilderReceiver) = apply { delegate.builder.block() } - // + // endregion [overrides] } @ExperimentalKotlinPoetApi diff --git a/kotlin-code-generation/src/main/kotlin/builder/KotlinEnumClassSpecBuilder.kt b/kotlin-code-generation/src/main/kotlin/builder/KotlinEnumClassSpecBuilder.kt index 909e32f..fbbe084 100644 --- a/kotlin-code-generation/src/main/kotlin/builder/KotlinEnumClassSpecBuilder.kt +++ b/kotlin-code-generation/src/main/kotlin/builder/KotlinEnumClassSpecBuilder.kt @@ -54,7 +54,7 @@ class KotlinEnumClassSpecBuilder internal constructor( override fun build(): KotlinEnumClassSpec = KotlinEnumClassSpec(className, delegate.build()) - // + // region [overrides] override fun addAnnotation(spec: KotlinAnnotationSpecSupplier) = apply { delegate.addAnnotation(spec.get()) } override fun contextReceivers(vararg receiverTypes: TypeName) = builder { this.contextReceivers(*receiverTypes) } override fun addFunction(funSpec: KotlinFunSpecSupplier) = apply { delegate.addFunction(funSpec.get()) } @@ -66,7 +66,7 @@ class KotlinEnumClassSpecBuilder internal constructor( override fun addType(typeSpec: TypeSpecSupplier) = builder { this.addType(typeSpec.get()) } override fun addTag(type: KClass<*>, tag: Any?) = builder { this.tag(type, tag) } override fun builder(block: TypeSpecBuilderReceiver): KotlinEnumClassSpecBuilder = apply { delegate.builder.block() } - // + // endregion [overrides] } @ExperimentalKotlinPoetApi diff --git a/kotlin-code-generation/src/main/kotlin/builder/KotlinFileSpecBuilder.kt b/kotlin-code-generation/src/main/kotlin/builder/KotlinFileSpecBuilder.kt index 6bfbc1a..77356d2 100644 --- a/kotlin-code-generation/src/main/kotlin/builder/KotlinFileSpecBuilder.kt +++ b/kotlin-code-generation/src/main/kotlin/builder/KotlinFileSpecBuilder.kt @@ -94,7 +94,7 @@ class KotlinFileSpecBuilder internal constructor( return KotlinFileSpec(spec = spec) } - // + // region [overrides] override val className: ClassName = delegate.className override fun addAnnotation(spec: KotlinAnnotationSpecSupplier) = apply { delegate.addAnnotation(spec.get()) } override fun addFunction(funSpec: KotlinFunSpecSupplier) = apply { delegate.addFunction(funSpec.get()) } @@ -104,7 +104,7 @@ class KotlinFileSpecBuilder internal constructor( override fun builder(block: FileSpecBuilderReceiver) = apply { delegate.builder.block() } override fun get(): FileSpec = build().get() override fun spec(): KotlinFileSpec = build() - // + // endregion [overrides] } @ExperimentalKotlinPoetApi diff --git a/kotlin-code-generation/src/main/kotlin/builder/KotlinFunSpecBuilder.kt b/kotlin-code-generation/src/main/kotlin/builder/KotlinFunSpecBuilder.kt index 9124a99..47916ac 100644 --- a/kotlin-code-generation/src/main/kotlin/builder/KotlinFunSpecBuilder.kt +++ b/kotlin-code-generation/src/main/kotlin/builder/KotlinFunSpecBuilder.kt @@ -123,7 +123,7 @@ class KotlinFunSpecBuilder internal constructor( override fun build(): KotlinFunSpec = KotlinFunSpec(spec = delegate.build()) - // + // region [overrides] override fun addAnnotation(spec: KotlinAnnotationSpecSupplier) = apply { delegate.addAnnotation(spec.get()) } override fun contextReceivers(vararg receiverTypes: TypeName) = builder { this.contextReceivers(*receiverTypes) } override fun addKdoc(kdoc: KDoc) = apply { delegate.addKdoc(kdoc.get()) } @@ -132,7 +132,7 @@ class KotlinFunSpecBuilder internal constructor( override fun builder(block: FunSpecBuilderReceiver): KotlinFunSpecBuilder = apply { delegate.builder.block() } override fun get(): FunSpec = build().get() override fun spec(): KotlinFunSpec = build() - // + // endregion [overrides] } @ExperimentalKotlinPoetApi diff --git a/kotlin-code-generation/src/main/kotlin/builder/KotlinInterfaceSpecBuilder.kt b/kotlin-code-generation/src/main/kotlin/builder/KotlinInterfaceSpecBuilder.kt index 8dcb9f5..9b0e314 100644 --- a/kotlin-code-generation/src/main/kotlin/builder/KotlinInterfaceSpecBuilder.kt +++ b/kotlin-code-generation/src/main/kotlin/builder/KotlinInterfaceSpecBuilder.kt @@ -52,7 +52,7 @@ class KotlinInterfaceSpecBuilder internal constructor( override fun build(): KotlinInterfaceSpec = KotlinInterfaceSpec(className = className, spec = delegate.build()) - // + // region [overrides] override fun addAnnotation(spec: KotlinAnnotationSpecSupplier) = apply { delegate.addAnnotation(spec.get()) } override fun contextReceivers(vararg receiverTypes: TypeName) = builder { this.contextReceivers(*receiverTypes) } override fun addFunction(funSpec: KotlinFunSpecSupplier) = apply { delegate.addFunction(funSpec.get()) } @@ -64,7 +64,7 @@ class KotlinInterfaceSpecBuilder internal constructor( override fun addSuperinterface(superinterface: TypeName, delegate: CodeBlock) = builder { this.addSuperinterface(superinterface, delegate) } override fun addTag(type: KClass<*>, tag: Any?) = builder { this.tag(type, tag) } override fun builder(block: TypeSpecBuilderReceiver) = apply { delegate.builder.block() } - // + // endregion [overrides] } @ExperimentalKotlinPoetApi diff --git a/kotlin-code-generation/src/main/kotlin/builder/KotlinObjectSpecBuilder.kt b/kotlin-code-generation/src/main/kotlin/builder/KotlinObjectSpecBuilder.kt index a6542b4..d72f7e6 100644 --- a/kotlin-code-generation/src/main/kotlin/builder/KotlinObjectSpecBuilder.kt +++ b/kotlin-code-generation/src/main/kotlin/builder/KotlinObjectSpecBuilder.kt @@ -50,7 +50,7 @@ class KotlinObjectSpecBuilder internal constructor( override fun build(): KotlinObjectSpec = KotlinObjectSpec(className = className, spec = delegate.build()) - // + // region [overrides] override fun addAnnotation(spec: KotlinAnnotationSpecSupplier) = apply { delegate.addAnnotation(spec.get()) } override fun contextReceivers(vararg receiverTypes: TypeName) = builder { this.contextReceivers(*receiverTypes) } override fun addFunction(funSpec: KotlinFunSpecSupplier) = apply { delegate.addFunction(funSpec.get()) } @@ -62,7 +62,7 @@ class KotlinObjectSpecBuilder internal constructor( override fun addType(typeSpec: TypeSpecSupplier) = builder { this.addType(typeSpec.get()) } override fun addTag(type: KClass<*>, tag: Any?) = builder { this.tag(type, tag) } override fun builder(block: TypeSpecBuilderReceiver): KotlinObjectSpecBuilder = apply { delegate.builder.block() } - // + // endregion [overrides] } @ExperimentalKotlinPoetApi diff --git a/kotlin-code-generation/src/main/kotlin/builder/KotlinParameterSpecBuilder.kt b/kotlin-code-generation/src/main/kotlin/builder/KotlinParameterSpecBuilder.kt index c0bbed1..6c97c54 100644 --- a/kotlin-code-generation/src/main/kotlin/builder/KotlinParameterSpecBuilder.kt +++ b/kotlin-code-generation/src/main/kotlin/builder/KotlinParameterSpecBuilder.kt @@ -81,7 +81,7 @@ class KotlinParameterSpecBuilder internal constructor( override fun build(): KotlinParameterSpec = KotlinParameterSpec(spec = delegate.build()) - // + // region [overrides] override fun addAnnotation(spec: KotlinAnnotationSpecSupplier) = apply { delegate.addAnnotation(spec.get()) } override fun addKdoc(kdoc: KDoc) = apply { delegate.addKdoc(kdoc.get()) } override fun addModifiers(vararg modifiers: KModifier) = builder { this.addModifiers(*modifiers) } @@ -89,7 +89,7 @@ class KotlinParameterSpecBuilder internal constructor( override fun builder(block: ParameterSpecBuilderReceiver) = apply { delegate.builder.block() } override fun get(): ParameterSpec = build().get() override fun spec(): KotlinParameterSpec = build() - // + // endregion [overrides] } @ExperimentalKotlinPoetApi diff --git a/kotlin-code-generation/src/main/kotlin/builder/KotlinPropertySpecBuilder.kt b/kotlin-code-generation/src/main/kotlin/builder/KotlinPropertySpecBuilder.kt index 697faa0..2b974e8 100644 --- a/kotlin-code-generation/src/main/kotlin/builder/KotlinPropertySpecBuilder.kt +++ b/kotlin-code-generation/src/main/kotlin/builder/KotlinPropertySpecBuilder.kt @@ -90,7 +90,7 @@ class KotlinPropertySpecBuilder internal constructor( override fun build(): KotlinPropertySpec = KotlinPropertySpec(spec = delegate.build()) - // + // region [overrides] override fun addAnnotation(spec: KotlinAnnotationSpecSupplier) = apply { delegate.addAnnotation(spec.get()) } override fun contextReceivers(vararg receiverTypes: TypeName) = builder { this.contextReceivers(*receiverTypes) } override fun addKdoc(kdoc: KDoc): KotlinPropertySpecBuilder = apply { delegate.addKdoc(kdoc.get()) } @@ -99,7 +99,7 @@ class KotlinPropertySpecBuilder internal constructor( override fun builder(block: PropertySpecBuilderReceiver) = apply { delegate.builder.block() } override fun get(): PropertySpec = build().get() override fun spec(): KotlinPropertySpec = build() - // + // endregion [overrides] } @ExperimentalKotlinPoetApi diff --git a/kotlin-code-generation/src/main/kotlin/builder/KotlinTypeAliasSpecBuilder.kt b/kotlin-code-generation/src/main/kotlin/builder/KotlinTypeAliasSpecBuilder.kt index 51c75dd..f1daaa4 100644 --- a/kotlin-code-generation/src/main/kotlin/builder/KotlinTypeAliasSpecBuilder.kt +++ b/kotlin-code-generation/src/main/kotlin/builder/KotlinTypeAliasSpecBuilder.kt @@ -41,7 +41,7 @@ class KotlinTypeAliasSpecBuilder internal constructor( override fun build() = KotlinTypeAliasSpec(spec = delegate.build()) - // + // region [overrides] override fun addAnnotation(spec: KotlinAnnotationSpecSupplier) = apply { delegate.addAnnotation(spec.get()) } override fun addKdoc(kdoc: KDoc) = apply { delegate.addKdoc(kdoc.get()) } override fun addModifiers(vararg modifiers: KModifier) = builder { this.addModifiers(*modifiers) } @@ -49,7 +49,7 @@ class KotlinTypeAliasSpecBuilder internal constructor( override fun builder(block: TypeAliasSpecBuilderReceiver) = apply { delegate.builder.block() } override fun get(): TypeAliasSpec = build().get() override fun spec(): KotlinTypeAliasSpec = build() - // + // endregion [overrides] } @ExperimentalKotlinPoetApi diff --git a/kotlin-code-generation/src/main/kotlin/builder/KotlinValueClassSpecBuilder.kt b/kotlin-code-generation/src/main/kotlin/builder/KotlinValueClassSpecBuilder.kt index 78bf92e..3952a16 100644 --- a/kotlin-code-generation/src/main/kotlin/builder/KotlinValueClassSpecBuilder.kt +++ b/kotlin-code-generation/src/main/kotlin/builder/KotlinValueClassSpecBuilder.kt @@ -75,7 +75,7 @@ class KotlinValueClassSpecBuilder internal constructor( return KotlinValueClassSpec(className = className, spec = delegate.build()) } - // + // region [overrides] override fun addAnnotation(spec: KotlinAnnotationSpecSupplier) = apply { delegate.addAnnotation(spec.get()) } override fun addConstructorProperty(spec: KotlinConstructorPropertySpecSupplier) = apply { this.constructorProperty = spec } override fun contextReceivers(vararg receiverTypes: TypeName) = builder { this.contextReceivers(*receiverTypes) } @@ -88,7 +88,7 @@ class KotlinValueClassSpecBuilder internal constructor( override fun addType(typeSpec: TypeSpecSupplier) = builder { this.addType(typeSpec.get()) } override fun addTag(type: KClass<*>, tag: Any?) = builder { this.tag(type, tag) } override fun builder(block: TypeSpecBuilderReceiver) = apply { delegate.builder.block() } - // + // endregion [overrides] } @ExperimentalKotlinPoetApi diff --git a/kotlin-code-generation/src/main/kotlin/spec/KotlinFileSpec.kt b/kotlin-code-generation/src/main/kotlin/spec/KotlinFileSpec.kt index 321611a..8f67751 100644 --- a/kotlin-code-generation/src/main/kotlin/spec/KotlinFileSpec.kt +++ b/kotlin-code-generation/src/main/kotlin/spec/KotlinFileSpec.kt @@ -70,7 +70,7 @@ value class KotlinFileSpecList(private val fileSpecs: List) : Li /** * Create new instance from single spec. */ - constructor(fileSpec: KotlinFileSpec) : this(listOf(fileSpec)) + constructor(vararg fileSpec: KotlinFileSpec) : this(fileSpec.toList()) /** * Create copy of this list and add new spec(s). diff --git a/kotlin-code-generation/src/main/kotlin/support/ThrowsAnnotation.kt b/kotlin-code-generation/src/main/kotlin/support/ThrowsAnnotation.kt index 27a436e..5c5c5f5 100644 --- a/kotlin-code-generation/src/main/kotlin/support/ThrowsAnnotation.kt +++ b/kotlin-code-generation/src/main/kotlin/support/ThrowsAnnotation.kt @@ -12,6 +12,9 @@ import io.toolisticon.kotlin.generation.support.CodeBlockArray.Companion.Format import kotlin.collections.fold import kotlin.reflect.KClass +/** + * Creates a `@Throws` annotation. + */ @ExperimentalKotlinPoetApi data class ThrowsAnnotation(private val members: CodeBlockArray) : KotlinAnnotationSpecSupplier { companion object { @@ -20,8 +23,19 @@ data class ThrowsAnnotation(private val members: CodeBlockArray) : Ko private val TypeName.codeBlock: CodeBlock get() = CodeBlock.of(FORMAT_KCLASS, this) } + /** + * Create new instance. + */ constructor(exceptions: List) : this(members = exceptions.fold(EMPTY) { acc, cur -> acc + cur.codeBlock }) + + /** + * Create new instance. + */ constructor(exception: TypeName, vararg exceptions: TypeName) : this(listOf(exception, *exceptions)) + + /** + * Create new instance. + */ constructor(exception: KClass, vararg exceptions: KClass) : this(listOf(exception, *exceptions).map { it.asTypeName() }) override fun spec(): KotlinAnnotationSpec = buildAnnotation(EXCEPTION) { diff --git a/pom.xml b/pom.xml index 2f5470b..3225960 100644 --- a/pom.xml +++ b/pom.xml @@ -1,11 +1,11 @@ - 4.0.0 io.toolisticon.maven.parent maven-parent-kotlin-base - 2024.9.0 + 2024.9.2