Skip to content

Commit

Permalink
Merge pull request #146 from InsertKoinIO/rc3_fix_skip_isExpect
Browse files Browse the repository at this point in the history
RC3 - fix skip is expect
  • Loading branch information
arnaudgiuliani authored Jul 22, 2024
2 parents 74ed722 + 82668a2 commit af23e7b
Show file tree
Hide file tree
Showing 10 changed files with 83 additions and 59 deletions.
29 changes: 14 additions & 15 deletions docs/setup/annotations.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,10 @@ Here are the current available Koin projects versions:

## KSP Plugin

We need KSP Plugin to work (https://github.com/google/ksp). Just add the Gradle plugin:
We need KSP Plugin to work (https://github.com/google/ksp). Follow the official (KSP Setup documentation)[https://kotlinlang.org/docs/ksp-quickstart.html]

Just add the Gradle plugin:
```groovy
ksp_version = "1.8.21-1.0.11"
```

```groovy
//at your project root
plugins {
id "com.google.devtools.ksp" version "$ksp_version"
}
Expand All @@ -42,22 +37,26 @@ plugins {
Here below how you can configure a Kotlin (even a Ktor) app:

```groovy
// Use KSP Plugin
apply plugin: 'com.google.devtools.ksp'
// Use KSP Generated sources
sourceSets.main {
java.srcDirs("build/generated/ksp/main/kotlin")
}
dependencies {
// Koin
compile "io.insert-koin:koin-core:$koin_version"
// Koin Annotations
compile "io.insert-koin:koin-annotations:$koin_ksp_version"
ksp "io.insert-koin:koin-ksp-compiler:$koin_ksp_version"
}
```

Check to add sourceSets config:

```groovy
// Use KSP Generated sources
sourceSets.main {
java.srcDirs("build/generated/ksp/main/kotlin")
}
```

## Android App Setup

Here below how you can configure an Android app:
Expand Down
2 changes: 1 addition & 1 deletion examples/gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# Core
kotlin = "1.9.24"
koin = "3.5.6"
koinAnnotations = "1.4.0-RC2"
koinAnnotations = "1.4.0-RC3"
ksp = "1.9.24-1.0.20"
junit = "4.13.2"
# Android
Expand Down
2 changes: 1 addition & 1 deletion projects/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ org.gradle.parallel=true
#Kotlin
kotlin.code.style=official
#Koin
koinAnnotationsVersion=1.4.0-RC2
koinAnnotationsVersion=1.4.0-RC3
#Android
android.useAndroidX=true
androidMinSDK=14
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class BuilderProcessor(
val defaultModule = KoinMetaData.Module(
packageName = "",
name = "defaultModule",
isDefault = true
isDefault = true,
)

logger.logging("Scan metadata ...")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,26 @@ const val NEW_LINE = "\n\t"


fun OutputStream.generateDefinition(def: KoinMetaData.Definition, isExternalDefinition: Boolean = false, label: () -> String) {
LOGGER.logging("generate ${def.label} - $def")
val param = def.parameters.generateParamFunction()
val ctor = generateConstructor(def.parameters)
val binds = generateBindings(def.bindings)
val qualifier = def.qualifier.generateQualifier()
val createAtStart = if (def.isType(SINGLE) && def.isCreatedAtStart == true) {
if (qualifier == "") CREATED_AT_START else ",$CREATED_AT_START"
} else ""
val space = if (def.isScoped()) NEW_LINE + "\t" else NEW_LINE

if (isExternalDefinition) {
writeExternalDefinitionFunction(def, qualifier, createAtStart, param, label, ctor, binds)
}
else {
writeDefinition(space, def, qualifier, createAtStart, param, label, ctor, binds)
if (def.isExpect.not()){
LOGGER.logging("generate ${def.label} - $def")
val param = def.parameters.generateParamFunction()
val ctor = generateConstructor(def.parameters)
val binds = generateBindings(def.bindings)
val qualifier = def.qualifier.generateQualifier()
val createAtStart = if (def.isType(SINGLE) && def.isCreatedAtStart == true) {
if (qualifier == "") CREATED_AT_START else ",$CREATED_AT_START"
} else ""
val space = if (def.isScoped()) NEW_LINE + "\t" else NEW_LINE

if (isExternalDefinition) {
writeExternalDefinitionFunction(def, qualifier, createAtStart, param, label, ctor, binds)
}
else {
writeDefinition(space, def, qualifier, createAtStart, param, label, ctor, binds)
}
} else {
LOGGER.warn("skip generate ${def.label} - isExpect")
appendText("// no definition for ${def.label} - isExpect")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ fun generateClassModule(classFile: OutputStream, module: KoinMetaData.Module, is
}
}

if (module.definitions.isNotEmpty()) {
if (module.definitions.isNotEmpty() && module.isExpect.not()) {
if (module.definitions.any {
// if any definition is a class function, we need to instantiate the module instance
// to able to call the function on this instance.
Expand All @@ -79,10 +79,14 @@ fun generateClassModule(classFile: OutputStream, module: KoinMetaData.Module, is
generateDefinitions(module, classFile)
}

if (module.externalDefinitions.isNotEmpty()) {
if (module.externalDefinitions.isNotEmpty() && module.isExpect.not()) {
classFile.generateExternalDefinitionCalls(module)
}

if (module.isExpect){
classFile.appendText("\n// empty module due to isExpect")
}

classFile.appendText("\n}")
val visibilityString = module.visibility.toSourceString()
classFile.appendText(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ sealed class KoinMetaData {
val includes: List<KSDeclaration>? = null,
val isCreatedAtStart: Boolean? = null,
val visibility: Visibility = Visibility.PUBLIC,
val isDefault: Boolean = false
val isDefault: Boolean = false,
val isExpect : Boolean = false
) : KoinMetaData() {

fun packageName(separator: String): String {
Expand Down Expand Up @@ -120,6 +121,7 @@ sealed class KoinMetaData {
val keyword: DefinitionAnnotation,
val bindings: List<KSDeclaration>,
val scope: Scope? = null,
val isExpect : Boolean
) : KoinMetaData() {

fun isScoped(): Boolean = scope != null
Expand Down Expand Up @@ -156,8 +158,9 @@ sealed class KoinMetaData {
val functionName: String,
parameters: List<DefinitionParameter> = emptyList(),
bindings: List<KSDeclaration>,
scope: Scope? = null
) : Definition(functionName, parameters, packageName, qualifier, isCreatedAtStart, keyword, bindings, scope) {
scope: Scope? = null,
isExpect : Boolean
) : Definition(functionName, parameters, packageName, qualifier, isCreatedAtStart, keyword, bindings, scope, isExpect) {
var isClassFunction: Boolean = true
}

Expand All @@ -169,7 +172,8 @@ sealed class KoinMetaData {
val className: String,
val constructorParameters: List<DefinitionParameter> = emptyList(),
bindings: List<KSDeclaration>,
scope: Scope? = null
scope: Scope? = null,
isExpect : Boolean
) : Definition(
className,
constructorParameters,
Expand All @@ -178,7 +182,8 @@ sealed class KoinMetaData {
isCreatedAtStart,
keyword,
bindings,
scope
scope,
isExpect
)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,30 +53,31 @@ class ClassComponentScanner(
val defaultBindings = ksClassDeclaration.superTypes.map { it.resolve().declaration }.toList()
val allBindings: List<KSDeclaration> = if (declaredBindings?.hasDefaultUnitValue() == false) declaredBindings else defaultBindings
val ctorParams = ksClassDeclaration.primaryConstructor?.parameters?.getParameters()
val isExpect = ksClassDeclaration.isExpect

return when (annotationName) {
SINGLE.annotationName -> {
createSingleDefinition(annotation, packageName, qualifier, className, ctorParams, allBindings)
createSingleDefinition(annotation, packageName, qualifier, className, ctorParams, allBindings, isExpect)
}
SINGLETON.annotationName -> {
createSingleDefinition(annotation, packageName, qualifier, className, ctorParams, allBindings)
createSingleDefinition(annotation, packageName, qualifier, className, ctorParams, allBindings, isExpect)
}
FACTORY.annotationName -> {
createClassDefinition(FACTORY,packageName, qualifier, className, ctorParams, allBindings)
createClassDefinition(FACTORY,packageName, qualifier, className, ctorParams, allBindings, isExpect = isExpect)
}
KOIN_VIEWMODEL.annotationName -> {
createClassDefinition(KOIN_VIEWMODEL,packageName, qualifier, className, ctorParams, allBindings)
createClassDefinition(KOIN_VIEWMODEL,packageName, qualifier, className, ctorParams, allBindings, isExpect = isExpect)
}
KOIN_WORKER.annotationName -> {
createClassDefinition(KOIN_WORKER,packageName, qualifier, className, ctorParams, allBindings)
createClassDefinition(KOIN_WORKER,packageName, qualifier, className, ctorParams, allBindings, isExpect = isExpect)
}
SCOPE.annotationName -> {
val scopeData : KoinMetaData.Scope = annotation.arguments.getScope()
val extraAnnotationDefinition = getExtraScopeAnnotation(annotations)
val extraAnnotation = annotations[extraAnnotationDefinition?.annotationName]
val extraDeclaredBindings = extraAnnotation?.let { declaredBindings(it) }
val extraScopeBindings = if(extraDeclaredBindings?.hasDefaultUnitValue() == false) extraDeclaredBindings else allBindings
createClassDefinition(extraAnnotationDefinition ?: SCOPE,packageName, qualifier, className, ctorParams, extraScopeBindings,scope = scopeData)
createClassDefinition(extraAnnotationDefinition ?: SCOPE,packageName, qualifier, className, ctorParams, extraScopeBindings,scope = scopeData, isExpect = isExpect)
}
else -> error("Unknown annotation type: $annotationName")
}
Expand All @@ -88,11 +89,12 @@ class ClassComponentScanner(
qualifier: String?,
className: String,
ctorParams: List<KoinMetaData.DefinitionParameter>?,
allBindings: List<KSDeclaration>
allBindings: List<KSDeclaration>,
isExpect : Boolean,
): KoinMetaData.Definition.ClassDefinition {
val createdAtStart: Boolean =
annotation.arguments.firstOrNull { it.name?.asString() == "createdAtStart" }?.value as Boolean? ?: false
return createClassDefinition(SINGLE, packageName, qualifier, className, ctorParams, allBindings, isCreatedAtStart = createdAtStart)
return createClassDefinition(SINGLE, packageName, qualifier, className, ctorParams, allBindings, isCreatedAtStart = createdAtStart, isExpect= isExpect)
}

private fun createClassDefinition(
Expand All @@ -104,6 +106,7 @@ class ClassComponentScanner(
allBindings: List<KSDeclaration>,
isCreatedAtStart : Boolean? = null,
scope: KoinMetaData.Scope? = null,
isExpect : Boolean,
): KoinMetaData.Definition.ClassDefinition {
return KoinMetaData.Definition.ClassDefinition(
packageName = packageName,
Expand All @@ -113,7 +116,8 @@ class ClassComponentScanner(
constructorParameters = ctorParams ?: emptyList(),
bindings = allBindings,
keyword = keyword,
scope = scope
scope = scope,
isExpect = isExpect
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,27 +42,28 @@ abstract class FunctionScanner(
val returnedType: KSDeclaration? = ksFunctionDeclaration.returnType?.resolve()?.declaration
val allBindings: List<KSDeclaration> = returnedType?.let { foundBindings + it } ?: foundBindings
val functionParameters = ksFunctionDeclaration.parameters.getParameters()
val isExpect = ksFunctionDeclaration.isExpect

return when (annotationName) {
SINGLE.annotationName -> {
createSingleDefinition(annotation, packageName, qualifier, functionName, functionParameters, allBindings)
createSingleDefinition(annotation, packageName, qualifier, functionName, functionParameters, allBindings, isExpect)
}
SINGLETON.annotationName -> {
createSingleDefinition(annotation, packageName, qualifier, functionName, functionParameters, allBindings)
createSingleDefinition(annotation, packageName, qualifier, functionName, functionParameters, allBindings, isExpect)
}
FACTORY.annotationName -> {
createDefinition(FACTORY,packageName,qualifier,functionName,functionParameters,allBindings)
createDefinition(FACTORY,packageName,qualifier,functionName,functionParameters,allBindings, isExpect = isExpect)
}
KOIN_VIEWMODEL.annotationName -> {
createDefinition(KOIN_VIEWMODEL,packageName,qualifier,functionName,functionParameters,allBindings)
createDefinition(KOIN_VIEWMODEL,packageName,qualifier,functionName,functionParameters,allBindings, isExpect = isExpect)
}
KOIN_WORKER.annotationName -> {
createDefinition(KOIN_WORKER,packageName,qualifier,functionName,functionParameters,allBindings)
createDefinition(KOIN_WORKER,packageName,qualifier,functionName,functionParameters,allBindings, isExpect = isExpect)
}
SCOPE.annotationName -> {
val scopeData : KoinMetaData.Scope = annotation.arguments.getScope()
val extraAnnotation = getExtraScopeAnnotation(annotations)
createDefinition(extraAnnotation ?: SCOPE,packageName,qualifier,functionName,functionParameters,allBindings,scope = scopeData)
createDefinition(extraAnnotation ?: SCOPE,packageName,qualifier,functionName,functionParameters,allBindings,scope = scopeData, isExpect = isExpect)
}
else -> null
}
Expand All @@ -74,7 +75,8 @@ abstract class FunctionScanner(
qualifier: String?,
functionName: String,
functionParameters: List<KoinMetaData.DefinitionParameter>,
allBindings: List<KSDeclaration>
allBindings: List<KSDeclaration>,
isExpect : Boolean
): KoinMetaData.Definition.FunctionDefinition {
val createdAtStart: Boolean =
annotation.arguments.firstOrNull { it.name?.asString() == "createdAtStart" }?.value as Boolean?
Expand All @@ -86,7 +88,8 @@ abstract class FunctionScanner(
functionName,
functionParameters,
allBindings,
isCreatedAtStart = createdAtStart
isCreatedAtStart = createdAtStart,
isExpect = isExpect
)
}

Expand All @@ -99,6 +102,7 @@ abstract class FunctionScanner(
allBindings: List<KSDeclaration>,
isCreatedAtStart : Boolean? = null,
scope: KoinMetaData.Scope? = null,
isExpect : Boolean
): KoinMetaData.Definition.FunctionDefinition {
return KoinMetaData.Definition.FunctionDefinition(
packageName = packageName,
Expand All @@ -108,7 +112,8 @@ abstract class FunctionScanner(
parameters = parameters ?: emptyList(),
bindings = allBindings,
keyword = keyword,
scope = scope
scope = scope,
isExpect = isExpect
).apply { isClassFunction = isModuleFunction }
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class ModuleScanner(
val includes = getIncludedModules(annotations)
val isCreatedAtStart = getIsCreatedAtStart(annotations)
val componentScan = getComponentScan(annotations)
val isExpect = declaration.isExpect

val name = "$element"
val type = if (declaration.classKind == ClassKind.OBJECT) {
Expand All @@ -46,7 +47,8 @@ class ModuleScanner(
componentScan = componentScan,
includes = includes,
isCreatedAtStart = isCreatedAtStart,
visibility = declaration.getVisibility()
visibility = declaration.getVisibility(),
isExpect = isExpect
)

val annotatedFunctions = declaration.getAllFunctions()
Expand Down

0 comments on commit af23e7b

Please sign in to comment.