Skip to content
This repository was archived by the owner on Feb 26, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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)

}
Original file line number Diff line number Diff line change
@@ -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)
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -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<VariableElement>, sourceRoot: File) {
val packageName = processingEnv.elementUtils.getPackageOf(classToBuild).toString()
val builderClassName = "${classToBuild.simpleName}Builder"

val builderClassName = "${buildClassName(classToBuild, "_")}Builder"

processingEnv.noteMessage { "Writing $packageName.$builderClassName" }

Expand All @@ -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<VariableElement> {
val allMembers = processingEnv.elementUtils.getAllMembers(this)
Expand Down Expand Up @@ -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<Element>, 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()
Expand Down