From cf1383fa8b7b27f1225a8f1989afefd2a7a51291 Mon Sep 17 00:00:00 2001 From: Damiano Giusti Date: Tue, 14 Mar 2023 10:06:42 +0100 Subject: [PATCH 1/5] Map param name and default info in ConstructorParameter --- .../koin/compiler/metadata/KoinMetaData.kt | 29 +++++++++++++++---- .../org/koin/compiler/scanner/KspExt.kt | 14 +++++---- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/compiler/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/metadata/KoinMetaData.kt b/compiler/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/metadata/KoinMetaData.kt index 20c9f7f..216d12a 100644 --- a/compiler/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/metadata/KoinMetaData.kt +++ b/compiler/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/metadata/KoinMetaData.kt @@ -123,12 +123,31 @@ sealed class KoinMetaData { } sealed class ConstructorParameter(val nullable: Boolean = false) { - data class Dependency(val value: String? = null, val isNullable: Boolean = false, val kind : DependencyKind = DependencyKind.Single) : - ConstructorParameter(isNullable) - data class ParameterInject(val isNullable: Boolean = false) : ConstructorParameter(isNullable) - data class Property(val value: String? = null, val isNullable: Boolean = false) : - ConstructorParameter(isNullable) + abstract val name: String? + abstract val hasDefault: Boolean + + data class Dependency( + override val name: String?, + val value: String? = null, + val isNullable: Boolean = false, + override val hasDefault: Boolean, + val kind: DependencyKind = DependencyKind.Single + ) : ConstructorParameter(isNullable) + + + data class ParameterInject( + override val name: String?, + val isNullable: Boolean = false, + override val hasDefault: Boolean + ) : ConstructorParameter(isNullable) + + data class Property( + override val name: String?, + val value: String? = null, + val isNullable: Boolean = false, + override val hasDefault: Boolean + ) : ConstructorParameter(isNullable) } enum class DependencyKind { diff --git a/compiler/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/scanner/KspExt.kt b/compiler/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/scanner/KspExt.kt index 8fc4093..d26c428 100644 --- a/compiler/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/scanner/KspExt.kt +++ b/compiler/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/scanner/KspExt.kt @@ -73,21 +73,23 @@ private fun getConstructorParameter(param: KSValueParameter): KoinMetaData.Const val firstAnnotation = param.annotations.firstOrNull() val annotationName = firstAnnotation?.shortName?.asString() val annotationValue = firstAnnotation?.arguments?.getValueArgument() + val paramName = param.name?.asString() val resolvedType = param.type.resolve() val isNullable = resolvedType.isMarkedNullable + val hasDefault = param.hasDefault val resolvedTypeString = resolvedType.toString() //TODO check to see better way to detect this val isList = resolvedTypeString.startsWith("List<") val isLazy = resolvedTypeString.startsWith("Lazy<") return when (annotationName) { - "${InjectedParam::class.simpleName}" -> KoinMetaData.ConstructorParameter.ParameterInject(isNullable) - "${Property::class.simpleName}" -> KoinMetaData.ConstructorParameter.Property(annotationValue, isNullable) - "${Named::class.simpleName}" -> KoinMetaData.ConstructorParameter.Dependency(annotationValue, isNullable) + "${InjectedParam::class.simpleName}" -> KoinMetaData.ConstructorParameter.ParameterInject(name = paramName, isNullable = isNullable, hasDefault = hasDefault) + "${Property::class.simpleName}" -> KoinMetaData.ConstructorParameter.Property(name = paramName, value = annotationValue, isNullable, hasDefault) + "${Named::class.simpleName}" -> KoinMetaData.ConstructorParameter.Dependency(name = paramName, value = annotationValue, isNullable, hasDefault) else -> { - if (isList) KoinMetaData.ConstructorParameter.Dependency(kind = KoinMetaData.DependencyKind.List) - else if (isLazy) KoinMetaData.ConstructorParameter.Dependency(isNullable = isNullable, kind = KoinMetaData.DependencyKind.Lazy) - else KoinMetaData.ConstructorParameter.Dependency(isNullable = isNullable) + if (isList) KoinMetaData.ConstructorParameter.Dependency(name = paramName, hasDefault = hasDefault, kind = KoinMetaData.DependencyKind.List) + else if (isLazy) KoinMetaData.ConstructorParameter.Dependency(name = paramName, isNullable = isNullable, hasDefault = hasDefault, kind = KoinMetaData.DependencyKind.Lazy) + else KoinMetaData.ConstructorParameter.Dependency(name = paramName, isNullable = isNullable, hasDefault = hasDefault) } } } From ceb91b29dc78c86887241db1fcd4b7d2ebd5229c Mon Sep 17 00:00:00 2001 From: Damiano Giusti Date: Tue, 14 Mar 2023 10:07:06 +0100 Subject: [PATCH 2/5] Filter out params with default value when generating constructor invocation --- .../org/koin/compiler/generator/DefinitionGenerationExt.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/generator/DefinitionGenerationExt.kt b/compiler/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/generator/DefinitionGenerationExt.kt index 38c8027..15bf629 100644 --- a/compiler/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/generator/DefinitionGenerationExt.kt +++ b/compiler/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/generator/DefinitionGenerationExt.kt @@ -120,7 +120,8 @@ fun generateScope(scope: KoinMetaData.Scope): String { fun generateScopeClosing(): String = "${NEW_LINE}}" private fun generateConstructor(constructorParameters: List): String { - return constructorParameters.joinToString(prefix = "(", separator = ",", postfix = ")") { ctorParam -> + val paramsWithoutDefaultValues = constructorParameters.filter { !it.hasDefault } + return paramsWithoutDefaultValues.joinToString(prefix = "(", separator = ",", postfix = ")") { ctorParam -> val isNullable: Boolean = ctorParam.nullable when (ctorParam) { is KoinMetaData.ConstructorParameter.Dependency -> { From b2a81def1a8e8089e85b5d3a8ec4f23ff810b02c Mon Sep 17 00:00:00 2001 From: Damiano Giusti Date: Tue, 14 Mar 2023 10:07:38 +0100 Subject: [PATCH 3/5] Add param name as suffix to disambiguate constructor params when skipping default ones --- .../org/koin/compiler/generator/DefinitionGenerationExt.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/generator/DefinitionGenerationExt.kt b/compiler/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/generator/DefinitionGenerationExt.kt index 15bf629..2a2c936 100644 --- a/compiler/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/generator/DefinitionGenerationExt.kt +++ b/compiler/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/generator/DefinitionGenerationExt.kt @@ -132,7 +132,8 @@ private fun generateConstructor(constructorParameters: List Date: Tue, 14 Mar 2023 10:26:06 +0100 Subject: [PATCH 4/5] Add verification in sandbox --- .../example/newmodule/ComponentWithDefaultValues.kt | 13 +++++++++++++ .../src/test/kotlin/org.koin.example/TestModule.kt | 2 ++ 2 files changed, 15 insertions(+) create mode 100644 sandbox/other-ksp/src/main/kotlin/org/koin/example/newmodule/ComponentWithDefaultValues.kt diff --git a/sandbox/other-ksp/src/main/kotlin/org/koin/example/newmodule/ComponentWithDefaultValues.kt b/sandbox/other-ksp/src/main/kotlin/org/koin/example/newmodule/ComponentWithDefaultValues.kt new file mode 100644 index 0000000..463920d --- /dev/null +++ b/sandbox/other-ksp/src/main/kotlin/org/koin/example/newmodule/ComponentWithDefaultValues.kt @@ -0,0 +1,13 @@ +package org.koin.example.newmodule + +import org.koin.core.annotation.Single + +interface ComponentInterface { + + companion object Default : ComponentInterface +} + +@Single +class ComponentWithDefaultValues( + private val dependency: ComponentInterface = ComponentInterface.Default +) \ No newline at end of file diff --git a/sandbox/other-ksp/src/test/kotlin/org.koin.example/TestModule.kt b/sandbox/other-ksp/src/test/kotlin/org.koin.example/TestModule.kt index ea9f41a..650b71e 100644 --- a/sandbox/other-ksp/src/test/kotlin/org.koin.example/TestModule.kt +++ b/sandbox/other-ksp/src/test/kotlin/org.koin.example/TestModule.kt @@ -4,6 +4,7 @@ import org.junit.Test import org.koin.core.context.startKoin import org.koin.core.logger.Level import org.koin.example.`interface`.MyInterfaceExt +import org.koin.example.newmodule.ComponentWithDefaultValues import org.koin.example.newmodule.MyModule2 import org.koin.example.newmodule.MyOtherComponent2 import org.koin.example.newmodule.mymodule.MyModule3 @@ -27,5 +28,6 @@ class TestModule { koin.get() koin.get() koin.get() + koin.get() } } \ No newline at end of file From 20212d7f7e14b544f1dc776b63481c6c2321dad0 Mon Sep 17 00:00:00 2001 From: Arnaud Giuliani Date: Wed, 6 Sep 2023 15:58:35 +0200 Subject: [PATCH 5/5] fix config checker for default value --- .../kotlin/org/koin/compiler/verify/KoinConfigVerification.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/verify/KoinConfigVerification.kt b/compiler/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/verify/KoinConfigVerification.kt index e7f02ac..a92f9ed 100644 --- a/compiler/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/verify/KoinConfigVerification.kt +++ b/compiler/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/verify/KoinConfigVerification.kt @@ -47,7 +47,9 @@ class KoinConfigVerification(val codeGenerator: CodeGenerator, val logger: KSPLo def.parameters .filterIsInstance() .forEach { param -> - checkDependencyIsDefined(param, resolver, def) + if (!param.hasDefault){ + checkDependencyIsDefined(param, resolver, def) + } //TODO Check Cycle }