koin generator improvements

This commit is contained in:
InsanusMokrassar 2023-06-18 23:38:36 +06:00
parent 9824c3e00f
commit 7e5c88ddc3
3 changed files with 167 additions and 34 deletions

View File

@ -2,6 +2,12 @@
## 0.19.3
* `Koin`
* `Generator`
* New getter methods now available with opportunity to use parameters
* Old notation `*Single` and `*Factory` is deprecated since this release. With old
will be generated new `single*` and `factory*` notations for new generations
## 0.19.2
* `Versions`:

View File

@ -9,12 +9,17 @@ import com.google.devtools.ksp.processing.Resolver
import com.google.devtools.ksp.processing.SymbolProcessor
import com.google.devtools.ksp.symbol.KSAnnotated
import com.google.devtools.ksp.symbol.KSFile
import com.google.devtools.ksp.symbol.Modifier
import com.squareup.kotlinpoet.AnnotationSpec
import com.squareup.kotlinpoet.ClassName
import com.squareup.kotlinpoet.CodeBlock
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.KModifier
import com.squareup.kotlinpoet.ParameterSpec
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
import com.squareup.kotlinpoet.PropertySpec
import com.squareup.kotlinpoet.TypeVariableName
import com.squareup.kotlinpoet.asTypeName
import com.squareup.kotlinpoet.ksp.toClassName
import com.squareup.kotlinpoet.ksp.toTypeName
@ -22,6 +27,7 @@ import com.squareup.kotlinpoet.ksp.writeTo
import dev.inmo.micro_utils.koin.annotations.GenerateKoinDefinition
import org.koin.core.Koin
import org.koin.core.module.Module
import org.koin.core.parameter.ParametersDefinition
import org.koin.core.scope.Scope
import java.io.File
import kotlin.reflect.KClass
@ -104,57 +110,142 @@ class Processor(
addGetterProperty(Scope::class)
addGetterProperty(Koin::class)
if (it.generateSingle) {
val parametersDefinitionClassName = ClassName(
"org.koin.core.parameter",
"ParametersDefinition"
)
fun addGetterMethod(
receiver: KClass<*>
) {
addFunction(
FunSpec.builder("${it.name}Single").apply {
FunSpec.builder(
it.name
).apply {
addKdoc(
"""
Will register [definition] with [org.koin.core.module.Module.single] and key "${it.name}"
@return Definition by key "${it.name}" with [parameters]
""".trimIndent()
)
receiver(Module::class)
receiver(receiver)
addParameter(
ParameterSpec.builder(
"createdAtStart",
Boolean::class
).apply {
defaultValue("false")
}.build()
"parameters",
parametersDefinitionClassName,
KModifier.NOINLINE
)
addParameter(
ParameterSpec.builder(
"definition",
definitionClassName.parameterizedBy(targetType.copy(nullable = false))
).build()
)
returns(koinDefinitionClassName.parameterizedBy(targetType.copy(nullable = false)))
addModifiers(KModifier.INLINE)
addCode(
"return single(named(\"${it.name}\"), createdAtStart = createdAtStart, definition = definition)"
"return " + (if (it.nullable) {
"getOrNull"
} else {
"get"
}) + "(named(\"${it.name}\"), parameters)"
)
}.build()
)
}
if (it.generateFactory) {
addGetterMethod(Scope::class)
addGetterMethod(Koin::class)
if (it.generateSingle) {
fun FunSpec.Builder.configure(
useInstead: String? = null
) {
addKdoc(
"""
Will register [definition] with [org.koin.core.module.Module.single] and key "${it.name}"
""".trimIndent()
)
receiver(Module::class)
addParameter(
ParameterSpec.builder(
"createdAtStart",
Boolean::class
).apply {
defaultValue("false")
}.build()
)
addParameter(
ParameterSpec.builder(
"definition",
definitionClassName.parameterizedBy(targetType.copy(nullable = false))
).build()
)
returns(koinDefinitionClassName.parameterizedBy(targetType.copy(nullable = false)))
addCode(
"return single(named(\"${it.name}\"), createdAtStart = createdAtStart, definition = definition)"
)
if (useInstead != null) {
addAnnotation(
AnnotationSpec.builder(
Deprecated::class
).apply {
addMember(
CodeBlock.of(
"""
"This definition is old style and should not be used anymore. Use $useInstead instead"
""".trimIndent()
)
)
addMember(CodeBlock.of("ReplaceWith(\"$useInstead\")"))
}.build()
)
}
}
val actualSingleName = "single${it.name.replaceFirstChar { it.uppercase() }}"
addFunction(
FunSpec.builder("${it.name}Factory").apply {
addKdoc(
"""
FunSpec.builder("${it.name}Single").apply { configure(actualSingleName) }.build()
)
addFunction(
FunSpec.builder(actualSingleName).apply { configure() }.build()
)
}
if (it.generateFactory) {
fun FunSpec.Builder.configure(
useInstead: String? = null
) {
addKdoc(
"""
Will register [definition] with [org.koin.core.module.Module.factory] and key "${it.name}"
""".trimIndent()
)
receiver(Module::class)
addParameter(
ParameterSpec.builder(
"definition",
definitionClassName.parameterizedBy(targetType.copy(nullable = false))
).build()
)
returns(koinDefinitionClassName.parameterizedBy(targetType.copy(nullable = false)))
addCode(
"return factory(named(\"${it.name}\"), definition = definition)"
)
if (useInstead != null) {
addAnnotation(
AnnotationSpec.builder(
Deprecated::class
).apply {
addMember(
CodeBlock.of(
"""
"This definition is old style and should not be used anymore. Use $useInstead instead"
""".trimIndent()
)
)
addMember(CodeBlock.of("ReplaceWith(\"$useInstead\")"))
}.build()
)
receiver(Module::class)
addParameter(
ParameterSpec.builder(
"definition",
definitionClassName.parameterizedBy(targetType.copy(nullable = false))
).build()
)
returns(koinDefinitionClassName.parameterizedBy(targetType.copy(nullable = false)))
addCode(
"return factory(named(\"${it.name}\"), definition = definition)"
)
}.build()
}
}
val actualFactoryName = "factory${it.name.replaceFirstChar { it.uppercase() }}"
addFunction(
FunSpec.builder("${it.name}Factory").apply { configure(useInstead = actualFactoryName) }.build()
)
addFunction(
FunSpec.builder(actualFactoryName).apply { configure() }.build()
)
}
addImport("org.koin.core.qualifier", "named")

View File

@ -4,11 +4,14 @@
package dev.inmo.micro_utils.koin.generator.test
import kotlin.Boolean
import kotlin.Deprecated
import kotlin.String
import kotlin.Unit
import org.koin.core.Koin
import org.koin.core.definition.Definition
import org.koin.core.definition.KoinDefinition
import org.koin.core.module.Module
import org.koin.core.parameter.ParametersDefinition
import org.koin.core.qualifier.named
import org.koin.core.scope.Scope
@ -24,15 +27,48 @@ public val Scope.sampleInfo: Test<String>
public val Koin.sampleInfo: Test<String>
get() = get(named("sampleInfo"))
/**
* @return Definition by key "sampleInfo" with [parameters]
*/
public inline fun Scope.sampleInfo(noinline parameters: ParametersDefinition): Unit =
get(named("sampleInfo"), parameters)
/**
* @return Definition by key "sampleInfo" with [parameters]
*/
public inline fun Koin.sampleInfo(noinline parameters: ParametersDefinition): Unit =
get(named("sampleInfo"), parameters)
/**
* Will register [definition] with [org.koin.core.module.Module.single] and key "sampleInfo"
*/
@Deprecated(
"This definition is old style and should not be used anymore. Use singleSampleInfo instead",
ReplaceWith("singleSampleInfo"),
)
public fun Module.sampleInfoSingle(createdAtStart: Boolean = false,
definition: Definition<Test<String>>): KoinDefinition<Test<String>> =
single(named("sampleInfo"), createdAtStart = createdAtStart, definition = definition)
/**
* Will register [definition] with [org.koin.core.module.Module.single] and key "sampleInfo"
*/
public fun Module.singleSampleInfo(createdAtStart: Boolean = false,
definition: Definition<Test<String>>): KoinDefinition<Test<String>> =
single(named("sampleInfo"), createdAtStart = createdAtStart, definition = definition)
/**
* Will register [definition] with [org.koin.core.module.Module.factory] and key "sampleInfo"
*/
@Deprecated(
"This definition is old style and should not be used anymore. Use factorySampleInfo instead",
ReplaceWith("factorySampleInfo"),
)
public fun Module.sampleInfoFactory(definition: Definition<Test<String>>):
KoinDefinition<Test<String>> = factory(named("sampleInfo"), definition = definition)
/**
* Will register [definition] with [org.koin.core.module.Module.factory] and key "sampleInfo"
*/
public fun Module.factorySampleInfo(definition: Definition<Test<String>>):
KoinDefinition<Test<String>> = factory(named("sampleInfo"), definition = definition)