Skip to content

Commit

Permalink
Merge pull request #91 from InsertKoinIO/feature/constructor-with-def…
Browse files Browse the repository at this point in the history
…ault-arguments

Feature/constructor with default arguments
  • Loading branch information
arnaudgiuliani committed Sep 6, 2023
2 parents 704a55a + 20212d7 commit f53dc1c
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ fun generateScope(scope: KoinMetaData.Scope): String {
fun generateScopeClosing(): String = "${NEW_LINE}}"

private fun generateConstructor(constructorParameters: List<KoinMetaData.ConstructorParameter>): 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 -> {
Expand All @@ -132,7 +133,8 @@ private fun generateConstructor(constructorParameters: List<KoinMetaData.Constru
val qualifier =
ctorParam.value?.let { "qualifier=org.koin.core.qualifier.StringQualifier(\"${it}\")" }
?: ""
if (!isNullable) "$keyword($qualifier)" else "${keyword}OrNull($qualifier)"
val operator = if (!isNullable) "$keyword($qualifier)" else "${keyword}OrNull($qualifier)"
if (ctorParam.name == null) operator else "${ctorParam.name}=$operator"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,30 @@ sealed class KoinMetaData {
}

sealed class ConstructorParameter(val nullable: Boolean = false) {
data class Dependency(val value: String? = null, val isNullable: Boolean = false, val type : KSType, 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 type : KSType, 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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,22 +74,24 @@ 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: KSType = 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, type = resolvedType)
"${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, type = resolvedType)
else -> {
if (isList) KoinMetaData.ConstructorParameter.Dependency(kind = KoinMetaData.DependencyKind.List, type = resolvedType)
else if (isLazy) KoinMetaData.ConstructorParameter.Dependency(isNullable = isNullable, kind = KoinMetaData.DependencyKind.Lazy, type = resolvedType)
else KoinMetaData.ConstructorParameter.Dependency(isNullable = isNullable, type = resolvedType)
if (isList) KoinMetaData.ConstructorParameter.Dependency(name = paramName, hasDefault = hasDefault, kind = KoinMetaData.DependencyKind.List, type = resolvedType)
else if (isLazy) KoinMetaData.ConstructorParameter.Dependency(name = paramName, isNullable = isNullable, hasDefault = hasDefault, kind = KoinMetaData.DependencyKind.Lazy, type = resolvedType)
else KoinMetaData.ConstructorParameter.Dependency(name = paramName, isNullable = isNullable, hasDefault = hasDefault, type = resolvedType)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ class KoinConfigVerification(val codeGenerator: CodeGenerator, val logger: KSPLo
def.parameters
.filterIsInstance<KoinMetaData.ConstructorParameter.Dependency>()
.forEach { param ->
checkDependencyIsDefined(param, resolver, def)
if (!param.hasDefault){
checkDependencyIsDefined(param, resolver, def)
}

//TODO Check Cycle
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.koin.example.newmodule

import org.koin.core.annotation.Single

public interface ComponentInterface {

public companion object Default : ComponentInterface
}

@Single
public class ComponentWithDefaultValues(
private val dependency: ComponentInterface = ComponentInterface.Default
)
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import org.koin.example.animal.AnimalModule
import org.koin.example.animal.Cat
import org.koin.example.animal.Dog
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.MyOtherComponent3F
Expand All @@ -36,6 +37,7 @@ class TestModule {
koin.get<MyOtherComponent>()
koin.get<MyOtherComponent2>()
koin.get<MyOtherComponent3>()
koin.get<ComponentWithDefaultValues>()
koin.get<MyOtherComponent3F>()

val animals = (1..10).map { randomGetAnimal(koin) }
Expand Down

0 comments on commit f53dc1c

Please sign in to comment.