diff --git a/kotlin-builder-example-usage/src/main/kotlin/com/thinkinglogic/example/InnerDataClass.kt b/kotlin-builder-example-usage/src/main/kotlin/com/thinkinglogic/example/InnerDataClass.kt new file mode 100644 index 0000000..6b2d3e6 --- /dev/null +++ b/kotlin-builder-example-usage/src/main/kotlin/com/thinkinglogic/example/InnerDataClass.kt @@ -0,0 +1,18 @@ +package com.thinkinglogic.example + +import com.thinkinglogic.builder.annotation.Builder + +@Builder +data class InnerDataClass( + val constructorString: String, + private val privateString: String +) { + @Builder + data class DataClassInDataClass(val constructorString: String, + private val privateString: String) + + + data class DataClassInDataClassWithConstructor @Builder constructor(val constructorString: String, + private val privateString: String) + +} diff --git a/kotlin-builder-example-usage/src/test/kotlin/com/thinkinglogic/example/InnerDataClassTest.kt b/kotlin-builder-example-usage/src/test/kotlin/com/thinkinglogic/example/InnerDataClassTest.kt new file mode 100644 index 0000000..0cece4e --- /dev/null +++ b/kotlin-builder-example-usage/src/test/kotlin/com/thinkinglogic/example/InnerDataClassTest.kt @@ -0,0 +1,52 @@ +package com.thinkinglogic.example + +import assertk.assertions.contains +import assertk.assertions.isNotNull +import assertk.assertions.message +import assertk.catch +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class InnerDataClassTest { + + @Test + fun `builder should create sub object with correct properties`() { + // given + val privateString = "barfoo" + val expected = InnerDataClass.DataClassInDataClass( + constructorString = "foobar ", + privateString = privateString + ) + + // when + val actual = InnerDataClass_DataClassInDataClassBuilder() + .constructorString(expected.constructorString) + .privateString(privateString) + .build() + + // then + assertThat(actual).isEqualTo(expected) + } + + + @Test + fun `builder should create sub object with correct properties from constructor`() { + // given + val privateString = "barfoo" + val expected = InnerDataClass.DataClassInDataClassWithConstructor( + constructorString = "foobar ", + privateString = privateString + ) + + // when + val actual = InnerDataClass_DataClassInDataClassWithConstructorBuilder() + .constructorString(expected.constructorString) + .privateString(privateString) + .build() + + // then + assertThat(actual).isEqualTo(expected) + } + + +} diff --git a/kotlin-builder-processor/src/main/kotlin/com/thinkinglogic/builder/processor/BuilderProcessor.kt b/kotlin-builder-processor/src/main/kotlin/com/thinkinglogic/builder/processor/BuilderProcessor.kt index 3937aef..cc3e53e 100644 --- a/kotlin-builder-processor/src/main/kotlin/com/thinkinglogic/builder/processor/BuilderProcessor.kt +++ b/kotlin-builder-processor/src/main/kotlin/com/thinkinglogic/builder/processor/BuilderProcessor.kt @@ -82,7 +82,8 @@ class BuilderProcessor : AbstractProcessor() { /** Writes the source code to create a builder for [classToBuild] within the [sourceRoot] directory. */ private fun writeBuilder(classToBuild: TypeElement, fields: List, sourceRoot: File) { val packageName = processingEnv.elementUtils.getPackageOf(classToBuild).toString() - val builderClassName = "${classToBuild.simpleName}Builder" + + val builderClassName = "${buildClassName(classToBuild, "_")}Builder" processingEnv.noteMessage { "Writing $packageName.$builderClassName" } @@ -106,6 +107,16 @@ class BuilderProcessor : AbstractProcessor() { .writeTo(sourceRoot) } + private fun buildClassName(classToBuild: TypeElement, separator: String): String { + var className = classToBuild.simpleName.toString() + var clazz: Element = classToBuild.enclosingElement + while (clazz is TypeElement) { + className = clazz.simpleName.toString() + separator + className + clazz = clazz.enclosingElement + } + return className + } + /** Returns all fields in this type that also appear as a constructor parameter. */ private fun TypeElement.fieldsForBuilder(): List { val allMembers = processingEnv.elementUtils.getAllMembers(this) @@ -149,7 +160,7 @@ class BuilderProcessor : AbstractProcessor() { /** Creates a 'build()' function that will invoke a constructor for [returnType], passing [fields] as arguments and returning the new instance. */ private fun createBuildFunction(fields: List, returnType: TypeElement): FunSpec { val code = StringBuilder("$CHECK_REQUIRED_FIELDS_FUNCTION_NAME()") - code.appendln().append("returnĀ·${returnType.simpleName}(") + code.appendln().append("returnĀ·${buildClassName(returnType, ".")}(") val iterator = fields.listIterator() while (iterator.hasNext()) { val field = iterator.next()