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 ## 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 ## 0.19.2
* `Versions`: * `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.processing.SymbolProcessor
import com.google.devtools.ksp.symbol.KSAnnotated import com.google.devtools.ksp.symbol.KSAnnotated
import com.google.devtools.ksp.symbol.KSFile 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.ClassName
import com.squareup.kotlinpoet.CodeBlock
import com.squareup.kotlinpoet.FileSpec import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.FunSpec import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.KModifier
import com.squareup.kotlinpoet.ParameterSpec import com.squareup.kotlinpoet.ParameterSpec
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
import com.squareup.kotlinpoet.PropertySpec import com.squareup.kotlinpoet.PropertySpec
import com.squareup.kotlinpoet.TypeVariableName
import com.squareup.kotlinpoet.asTypeName import com.squareup.kotlinpoet.asTypeName
import com.squareup.kotlinpoet.ksp.toClassName import com.squareup.kotlinpoet.ksp.toClassName
import com.squareup.kotlinpoet.ksp.toTypeName 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 dev.inmo.micro_utils.koin.annotations.GenerateKoinDefinition
import org.koin.core.Koin import org.koin.core.Koin
import org.koin.core.module.Module import org.koin.core.module.Module
import org.koin.core.parameter.ParametersDefinition
import org.koin.core.scope.Scope import org.koin.core.scope.Scope
import java.io.File import java.io.File
import kotlin.reflect.KClass import kotlin.reflect.KClass
@ -104,57 +110,142 @@ class Processor(
addGetterProperty(Scope::class) addGetterProperty(Scope::class)
addGetterProperty(Koin::class) addGetterProperty(Koin::class)
if (it.generateSingle) { val parametersDefinitionClassName = ClassName(
"org.koin.core.parameter",
"ParametersDefinition"
)
fun addGetterMethod(
receiver: KClass<*>
) {
addFunction( addFunction(
FunSpec.builder("${it.name}Single").apply { FunSpec.builder(
it.name
).apply {
addKdoc( addKdoc(
""" """
Will register [definition] with [org.koin.core.module.Module.single] and key "${it.name}" @return Definition by key "${it.name}" with [parameters]
""".trimIndent() """.trimIndent()
) )
receiver(Module::class) receiver(receiver)
addParameter( addParameter(
ParameterSpec.builder( "parameters",
"createdAtStart", parametersDefinitionClassName,
Boolean::class KModifier.NOINLINE
).apply {
defaultValue("false")
}.build()
) )
addParameter( addModifiers(KModifier.INLINE)
ParameterSpec.builder(
"definition",
definitionClassName.parameterizedBy(targetType.copy(nullable = false))
).build()
)
returns(koinDefinitionClassName.parameterizedBy(targetType.copy(nullable = false)))
addCode( addCode(
"return single(named(\"${it.name}\"), createdAtStart = createdAtStart, definition = definition)" "return " + (if (it.nullable) {
"getOrNull"
} else {
"get"
}) + "(named(\"${it.name}\"), parameters)"
) )
}.build() }.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( addFunction(
FunSpec.builder("${it.name}Factory").apply { FunSpec.builder("${it.name}Single").apply { configure(actualSingleName) }.build()
addKdoc( )
"""
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}" Will register [definition] with [org.koin.core.module.Module.factory] and key "${it.name}"
""".trimIndent() """.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( val actualFactoryName = "factory${it.name.replaceFirstChar { it.uppercase() }}"
"definition", addFunction(
definitionClassName.parameterizedBy(targetType.copy(nullable = false)) FunSpec.builder("${it.name}Factory").apply { configure(useInstead = actualFactoryName) }.build()
).build() )
) addFunction(
returns(koinDefinitionClassName.parameterizedBy(targetType.copy(nullable = false))) FunSpec.builder(actualFactoryName).apply { configure() }.build()
addCode(
"return factory(named(\"${it.name}\"), definition = definition)"
)
}.build()
) )
} }
addImport("org.koin.core.qualifier", "named") addImport("org.koin.core.qualifier", "named")

View File

@ -4,11 +4,14 @@
package dev.inmo.micro_utils.koin.generator.test package dev.inmo.micro_utils.koin.generator.test
import kotlin.Boolean import kotlin.Boolean
import kotlin.Deprecated
import kotlin.String import kotlin.String
import kotlin.Unit
import org.koin.core.Koin import org.koin.core.Koin
import org.koin.core.definition.Definition import org.koin.core.definition.Definition
import org.koin.core.definition.KoinDefinition import org.koin.core.definition.KoinDefinition
import org.koin.core.module.Module import org.koin.core.module.Module
import org.koin.core.parameter.ParametersDefinition
import org.koin.core.qualifier.named import org.koin.core.qualifier.named
import org.koin.core.scope.Scope import org.koin.core.scope.Scope
@ -24,15 +27,48 @@ public val Scope.sampleInfo: Test<String>
public val Koin.sampleInfo: Test<String> public val Koin.sampleInfo: Test<String>
get() = get(named("sampleInfo")) 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" * 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, public fun Module.sampleInfoSingle(createdAtStart: Boolean = false,
definition: Definition<Test<String>>): KoinDefinition<Test<String>> = definition: Definition<Test<String>>): KoinDefinition<Test<String>> =
single(named("sampleInfo"), createdAtStart = createdAtStart, definition = definition) 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" * 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>>): public fun Module.sampleInfoFactory(definition: Definition<Test<String>>):
KoinDefinition<Test<String>> = factory(named("sampleInfo"), definition = definition) 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)