Skip to content

Commit

Permalink
Merge branch 'release/0.0.8'
Browse files Browse the repository at this point in the history
  • Loading branch information
jangalinski committed Sep 12, 2024
2 parents 94db706 + e4dbb90 commit d884a58
Show file tree
Hide file tree
Showing 35 changed files with 305 additions and 132 deletions.
2 changes: 1 addition & 1 deletion _build/parent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>io.toolisticon.kotlin.generation._</groupId>
<artifactId>kotlin-code-generation-root</artifactId>
<version>0.0.7</version>
<version>0.0.8</version>
<relativePath>../../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion _build/report-generator/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>io.toolisticon.kotlin.generation._</groupId>
<artifactId>kotlin-code-generation-parent</artifactId>
<version>0.0.7</version>
<version>0.0.8</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion _itest/builder-itest/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>io.toolisticon.kotlin.generation._</groupId>
<artifactId>kotlin-code-generation-itest-root</artifactId>
<version>0.0.7</version>
<version>0.0.8</version>
</parent>

<groupId>io.toolisticon.kotlin.generation.itest</groupId>
Expand Down
2 changes: 1 addition & 1 deletion _itest/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>io.toolisticon.kotlin.generation._</groupId>
<artifactId>kotlin-code-generation-parent</artifactId>
<version>0.0.7</version>
<version>0.0.8</version>
<relativePath>../_build/parent/pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion _itest/spi-itest/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>io.toolisticon.kotlin.generation._</groupId>
<artifactId>kotlin-code-generation-itest-root</artifactId>
<version>0.0.7</version>
<version>0.0.8</version>
</parent>

<groupId>io.toolisticon.kotlin.generation.itest</groupId>
Expand Down
2 changes: 1 addition & 1 deletion kotlin-code-generation-bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>io.toolisticon.kotlin.generation._</groupId>
<artifactId>kotlin-code-generation-root</artifactId>
<version>0.0.7</version>
<version>0.0.8</version>
</parent>

<groupId>io.toolisticon.kotlin.generation</groupId>
Expand Down
2 changes: 1 addition & 1 deletion kotlin-code-generation-test/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>io.toolisticon.kotlin.generation._</groupId>
<artifactId>kotlin-code-generation-parent</artifactId>
<version>0.0.7</version>
<version>0.0.8</version>
<relativePath>../_build/parent/pom.xml</relativePath>
</parent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package io.toolisticon.kotlin.generation.test.model
import com.squareup.kotlinpoet.ExperimentalKotlinPoetApi
import com.tschuchort.compiletesting.SourceFile
import io.toolisticon.kotlin.generation.spec.KotlinFileSpec
import io.toolisticon.kotlin.generation.spec.KotlinFileSpecs
import io.toolisticon.kotlin.generation.spec.KotlinFileSpecList
import io.toolisticon.kotlin.generation.test.KotlinCodeGenerationTest.sourceFile
import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi

Expand All @@ -13,10 +13,10 @@ import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi
@ExperimentalKotlinPoetApi
@ExperimentalCompilerApi
data class KotlinCompilationCommand(
val fileSpecs: KotlinFileSpecs
val fileSpecs: KotlinFileSpecList
) {

constructor(fileSpec: KotlinFileSpec) : this(KotlinFileSpecs(fileSpec))
constructor(fileSpec: KotlinFileSpec) : this(KotlinFileSpecList(fileSpec))

operator fun plus(fileSpec: KotlinFileSpec) = copy(fileSpecs = fileSpecs + fileSpec)

Expand Down
2 changes: 1 addition & 1 deletion kotlin-code-generation/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>io.toolisticon.kotlin.generation._</groupId>
<artifactId>kotlin-code-generation-parent</artifactId>
<version>0.0.7</version>
<version>0.0.8</version>
<relativePath>../_build/parent/pom.xml</relativePath>
</parent>

Expand Down
68 changes: 50 additions & 18 deletions kotlin-code-generation/src/main/kotlin/KotlinCodeGeneration.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,21 @@ import io.toolisticon.kotlin.generation.KotlinCodeGeneration.builder.propertyBui
import io.toolisticon.kotlin.generation.KotlinCodeGeneration.builder.runtimeExceptionClassBuilder
import io.toolisticon.kotlin.generation.KotlinCodeGeneration.builder.typeAliasBuilder
import io.toolisticon.kotlin.generation.KotlinCodeGeneration.builder.valueClassBuilder
import io.toolisticon.kotlin.generation.KotlinCodeGeneration.className
import io.toolisticon.kotlin.generation.builder.*
import io.toolisticon.kotlin.generation.builder.extra.*
import io.toolisticon.kotlin.generation.builder.extra.DelegateMapValueClassSpecBuilder.Companion.DEFAULT_KEY_TYPE
import io.toolisticon.kotlin.generation.poet.FormatSpecifier.asCodeBlock
import io.toolisticon.kotlin.generation.spec.*
import io.toolisticon.kotlin.generation.spi.KotlinCodeGenerationContext
import io.toolisticon.kotlin.generation.spi.KotlinCodeGenerationContextFactory
import io.toolisticon.kotlin.generation.spi.KotlinCodeGenerationSpiRegistry
import io.toolisticon.kotlin.generation.spi.KotlinCodeGenerationStrategy
import io.toolisticon.kotlin.generation.spi.registry.KotlinCodeGenerationServiceLoader
import io.toolisticon.kotlin.generation.spi.strategy.KotlinFileSpecStrategy
import io.toolisticon.kotlin.generation.spi.strategy.executeAll
import io.toolisticon.kotlin.generation.support.SUPPRESS_MEMBER_VISIBILITY_CAN_BE_PRIVATE
import mu.KLogging
import kotlin.reflect.KClass
import kotlin.reflect.full.isSubclassOf

/**
* Kotlin Code Generation is a wrapper lib for kotlin poet. This is the central class that allows access to builders and tools via simple static helpers.
Expand Down Expand Up @@ -559,34 +560,65 @@ object KotlinCodeGeneration : KLogging() {
const val NBSP = "·"
}

/**
* Generator Function that takes a context and an input, finds matching strategies and generates source file(s).
*
* Invokes the contextFactory and calls `generateFiles(context, input)`.
*
* @param INPUT the type of the input (base source of generation)
* @param CONTEXT the context (containing registry, ...) used for generation.
* @param input the instance of the input
* @param contextFactory factory fn to create the context (containing the spi registry) used for generation from input
* @return [KotlinFileSpecList] containing the generated files
* @throws IllegalStateException when no matching strategy is found.
*/
inline fun <reified CONTEXT : KotlinCodeGenerationContext<CONTEXT>, reified INPUT : Any> generateFiles(
contextFactory: KotlinCodeGenerationContextFactory<CONTEXT,INPUT>,
input: INPUT
): KotlinFileSpecList = generateFiles(context = contextFactory.invoke(input), input = input)

/**
* Generator Function that takes an input and generates source file(s).
* Generator Function that takes a context and an input, finds matching strategies and generates source file(s).
*
* @param INPUT the type of the input (base source of generation)
* @param CONTEXT the context (containing registry, ...) used for generation.
* @param STRATEGY the [KotlinFileSpecStrategy] to apply (using `executeAll()`
* @param input the instance of the input
* @param contextFactory fn that creates the context based on input.
* @return list of [KotlinFileSpec]
* @throws IllegalStateException when no strategy is found.
*/
inline fun <INPUT : Any,
CONTEXT : KotlinCodeGenerationContext<CONTEXT>,
reified STRATEGY : KotlinFileSpecStrategy<CONTEXT, INPUT>> generateFiles(
input: INPUT,
contextFactory: (INPUT) -> CONTEXT,
): List<KotlinFileSpec> {
val context = contextFactory.invoke(input)
val strategies: List<STRATEGY> = context.registry.strategies.filter(STRATEGY::class).mapNotNull {
* @param context the context (containing the spi registry) used for generation
* @return [KotlinFileSpecList] containing the generated files
* @throws IllegalStateException when no matching strategy is found.
*/
inline fun <reified CONTEXT : KotlinCodeGenerationContext<CONTEXT>, reified INPUT : Any> generateFiles(
context: CONTEXT,
input: INPUT
): KotlinFileSpecList {

val strategyCandidates = context.registry.strategies.filter { it.specType.isSubclassOf(KotlinFileSpecIterable::class) }
.filter { it.contextType.isSubclassOf(CONTEXT::class) }
.filter { it.inputType.isSubclassOf(INPUT::class) }
.map {
@Suppress("UNCHECKED_CAST")
it as KotlinCodeGenerationStrategy<CONTEXT, INPUT, KotlinFileSpecIterable>
}

// find all matching strategies
val matchingStrategies: List<KotlinCodeGenerationStrategy<CONTEXT, INPUT, KotlinFileSpecIterable>> = strategyCandidates.mapNotNull {
if (it.test(context, input)) {
it
} else {
logger.info { "strategy-filter: removing ${it.name}" }
null
}
}.also {
check(it.isNotEmpty()) { "No applicable strategy found/filtered for context=`${CONTEXT::class.simpleName}`, input=`${input::class.simpleName}`." }
}

// generate files
val sourceFiles = matchingStrategies.executeAll(context, input).flatten().also {
check(it.isNotEmpty()) { "No files where generated for context=`${CONTEXT::class.simpleName}`, input=`${input::class.simpleName}`." }
}
check(strategies.isNotEmpty()) { "No applicable strategy found/filtered for `${STRATEGY::class}`." }
return context.registry.strategies.filter(STRATEGY::class).executeAll(context, input)

// wrap to spec list
return KotlinFileSpecList(sourceFiles)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,26 @@ import com.squareup.kotlinpoet.ClassName
import com.squareup.kotlinpoet.ExperimentalKotlinPoetApi
import com.squareup.kotlinpoet.TypeSpec
import io.toolisticon.kotlin.generation.poet.KDoc
import io.toolisticon.kotlin.generation.poet.TypeSpecSupplier
import kotlin.reflect.KClass

/**
* Represents an annotation class.
*/
@ExperimentalKotlinPoetApi
data class KotlinAnnotationClassSpec(
override val className: ClassName,
private val spec: TypeSpec
) : KotlinGeneratorTypeSpec<KotlinAnnotationClassSpec>, TypeSpecSupplier, KotlinAnnotationClassSpecSupplier,
KotlinDocumentableSpec {
) : KotlinGeneratorTypeSpec<KotlinAnnotationClassSpec>, KotlinAnnotationClassSpecSupplier, KotlinDocumentableSpec {

override fun <T : Any> tag(type: KClass<T>): T? = get().tag(type)
override fun spec(): KotlinAnnotationClassSpec = this
override fun get(): TypeSpec = spec
override val kdoc: KDoc get() = KDoc(spec.kdoc)
}

/**
* Marks the builder and the spec so they are interchangeable.
*/
@ExperimentalKotlinPoetApi
interface KotlinAnnotationClassSpecSupplier : KotlinGeneratorSpecSupplier<KotlinAnnotationClassSpec>, ToFileTypeSpecSupplier {
override fun get(): TypeSpec = spec().get()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import com.squareup.kotlinpoet.TypeName
import io.toolisticon.kotlin.generation.builder.KotlinAnnotationSpecBuilder
import io.toolisticon.kotlin.generation.poet.AnnotationSpecSupplier

/**
* Represents an annotation, added to annotatable specs.
*/
data class KotlinAnnotationSpec(
private val spec: AnnotationSpec
) : KotlinGeneratorSpec<KotlinAnnotationSpec, AnnotationSpec, AnnotationSpecSupplier>, KotlinAnnotationSpecSupplier {
Expand All @@ -26,9 +29,15 @@ data class KotlinAnnotationSpec(
}
}

/**
* Marks the builder and the spec so they are interchangeable.
*/
interface KotlinAnnotationSpecSupplier : KotlinGeneratorSpecSupplier<KotlinAnnotationSpec>, AnnotationSpecSupplier {
override fun get(): AnnotationSpec = spec().get()
}

/**
* Create builder from spec.
*/
@ExperimentalKotlinPoetApi
fun KotlinAnnotationSpec.toBuilder() = KotlinAnnotationSpecBuilder.from(spec = this)
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,23 @@ import io.toolisticon.kotlin.generation.poet.KDoc
import io.toolisticon.kotlin.generation.poet.TypeSpecSupplier
import kotlin.reflect.KClass

@JvmInline
/**
* Represents an anonymous class.
*/
@ExperimentalKotlinPoetApi
value class KotlinAnonymousClassSpec(private val spec: TypeSpec) : KotlinGeneratorTypeSpec<KotlinAnonymousClassSpec>,
KotlinAnonymousClassSpecSupplier,
KotlinDocumentableSpec {
data class KotlinAnonymousClassSpec(
private val spec: TypeSpec
) : KotlinGeneratorTypeSpec<KotlinAnonymousClassSpec>, KotlinAnonymousClassSpecSupplier, KotlinDocumentableSpec {

override fun <T : Any> tag(type: KClass<T>): T? = get().tag(type)
override val kdoc: KDoc get() = KDoc(spec.kdoc)
override fun spec(): KotlinAnonymousClassSpec = this
override fun get(): TypeSpec = spec
}

/**
* Marks the builder and the spec so they are interchangeable.
*/
@ExperimentalKotlinPoetApi
interface KotlinAnonymousClassSpecSupplier : KotlinGeneratorSpecSupplier<KotlinAnonymousClassSpec>, TypeSpecSupplier {
override fun get(): TypeSpec = spec().get()
Expand Down
11 changes: 6 additions & 5 deletions kotlin-code-generation/src/main/kotlin/spec/KotlinClassSpec.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import com.squareup.kotlinpoet.TypeSpec
import io.toolisticon.kotlin.generation.poet.KDoc
import kotlin.reflect.KClass

/**
* Represents a class.
*/
@ExperimentalKotlinPoetApi
data class KotlinClassSpec(
override val className: ClassName,
Expand All @@ -18,11 +21,9 @@ data class KotlinClassSpec(
override fun get(): TypeSpec = spec
}

//fun KotlinDataClassSpec.toBuilder() = KotlinDataClassSpecBuilder.builder(spec = this)
//fun KotlinDataClassSpec.toFileSpec() = KotlinFileBuilder.builder(this).build()
// TODO fun KotlinDataClassSpec.toBuilder() = KotlinDataClassBuilder.from(spec = this)
// TODO fun KotlinDataClassSpec.toFileSpec() = KotlinFileSpecBuilder.builder(this).build()

/**
* Marks the builder and the spec so they are interchangeable.
*/
@ExperimentalKotlinPoetApi
interface KotlinClassSpecSupplier : KotlinGeneratorSpecSupplier<KotlinClassSpec>, ToFileTypeSpecSupplier {
override fun get(): TypeSpec = spec().get()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import io.toolisticon.kotlin.generation.poet.KDoc
import io.toolisticon.kotlin.generation.poet.TypeSpecSupplier
import kotlin.reflect.KClass

/**
* Represents a companion object.
*/
@ExperimentalKotlinPoetApi
data class KotlinCompanionObjectSpec(
private val spec: TypeSpec
Expand All @@ -17,6 +20,9 @@ data class KotlinCompanionObjectSpec(
override fun get(): TypeSpec = spec
}

/**
* Marks the builder and the spec so they are interchangeable.
*/
@ExperimentalKotlinPoetApi
interface KotlinCompanionObjectSpecSupplier : KotlinGeneratorSpecSupplier<KotlinCompanionObjectSpec>, TypeSpecSupplier {
override fun get(): TypeSpec = spec().get()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import com.squareup.kotlinpoet.TypeName
import io.toolisticon.kotlin.generation.poet.KDoc
import kotlin.reflect.KClass

/**
* Represents a constructor property, wraps parameter and property for easier
* creation of constructors with property..
*/
@ExperimentalKotlinPoetApi
data class KotlinConstructorPropertySpec(
val property: KotlinPropertySpec,
Expand All @@ -19,6 +23,9 @@ data class KotlinConstructorPropertySpec(
override fun spec(): KotlinConstructorPropertySpec = this
}

/**
* Marks the builder and the spec so they are interchangeable.
*/
@ExperimentalKotlinPoetApi
interface KotlinConstructorPropertySpecSupplier : KotlinGeneratorSpecSupplier<KotlinConstructorPropertySpec> {
/**
Expand All @@ -27,5 +34,8 @@ interface KotlinConstructorPropertySpecSupplier : KotlinGeneratorSpecSupplier<Ko
val name: String
}

/**
* Convert collection to list..
*/
@ExperimentalKotlinPoetApi
internal fun toList(constructorProperties: Collection<KotlinConstructorPropertySpecSupplier>) : List<KotlinConstructorPropertySpec> = constructorProperties.map(KotlinConstructorPropertySpecSupplier::spec).toList()
internal fun toList(constructorProperties: Collection<KotlinConstructorPropertySpecSupplier>): List<KotlinConstructorPropertySpec> = constructorProperties.map(KotlinConstructorPropertySpecSupplier::spec).toList()
Loading

0 comments on commit d884a58

Please sign in to comment.