Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KMP Code Generation Fix + Revamp Code Generation #156

Merged
merged 3 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/android-coffee-maker/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,5 @@ dependencies {

ksp {
arg("KOIN_CONFIG_CHECK","true")
arg("KOIN_DEFAULT_MODULE","false")
arg("KOIN_DEFAULT_MODULE","true")
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@ import org.koin.sample.androidx.data.ProvidedComponent
class MyProvidedComponent

@Factory
class MyPresenter(@InjectedParam val mainActivity: MainActivity, val context: Context, @Provided val provided : MyProvidedComponent)
class MyPresenter(@InjectedParam val mainActivity: MainActivity, val context: Context, @Provided val provided : MyProvidedComponent)

@Factory
class MyPresenterHolder(val mp : MyPresenter)
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
package org.koin.sample.androidx

import org.junit.Test
import org.koin.android.ext.android.getKoin
import org.koin.core.context.startKoin
import org.koin.core.context.stopKoin
import org.koin.core.parameter.parametersOf
import org.koin.ksp.generated.module
import org.koin.sample.android.library.CommonRepository
import org.koin.sample.android.library.MyScope
import org.koin.sample.androidx.app.MyPresenter
import org.koin.sample.androidx.app.ScopedStuff
import org.koin.sample.androidx.data.DataConsumer
import org.koin.sample.androidx.data.MyDataConsumer
import org.koin.sample.androidx.data.ProvidedComponent
import org.koin.sample.androidx.di.AppModule
import org.koin.sample.androidx.di.DataModule
import org.koin.sample.androidx.repository.RepositoryModule
Expand Down
2 changes: 1 addition & 1 deletion examples/android-library/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@ dependencies {

ksp {
arg("KOIN_CONFIG_CHECK","true")
arg("KOIN_DEFAULT_MODULE","false")
arg("KOIN_DEFAULT_MODULE","true")
}
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-RC3"
koinAnnotations = "1.4.0-RC4"
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-RC3
koinAnnotationsVersion=1.4.0-RC4
#Android
android.useAndroidX=true
androidMinSDK=14
Expand Down
6 changes: 6 additions & 0 deletions projects/koin-ksp-compiler/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,10 @@ kotlin {
}
}

tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
kotlinOptions {
freeCompilerArgs += listOf("-Xcontext-receivers")
}
}

apply(from = file("../gradle/publish.gradle.kts"))
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,27 @@ package org.koin.compiler
import com.google.devtools.ksp.processing.*
import com.google.devtools.ksp.symbol.KSAnnotated
import org.koin.compiler.KspOptions.*
import org.koin.compiler.generator.KoinGenerator
import org.koin.compiler.generator.KoinCodeGenerator
import org.koin.compiler.metadata.KoinMetaData
import org.koin.compiler.scanner.KoinMetaDataScanner
import org.koin.compiler.verify.KoinConfigVerification
import org.koin.compiler.verify.KoinConfigChecker
import org.koin.compiler.verify.KoinTagWriter

class BuilderProcessor(
private val codeGenerator: CodeGenerator,
codeGenerator: CodeGenerator,
private val logger: KSPLogger,
private val options: Map<String, String>
) : SymbolProcessor {

private val koinCodeGenerator = KoinGenerator(codeGenerator, logger, isComposeViewModelActive() || isKoinComposeViewModelActive())
private val isComposeViewModelActive = isComposeViewModelActive() || isKoinComposeViewModelActive()
private val koinCodeGenerator = KoinCodeGenerator(codeGenerator, logger, isComposeViewModelActive)
private val koinMetaDataScanner = KoinMetaDataScanner(logger)
private val koinConfigVerification = KoinConfigVerification(codeGenerator, logger)
private val koinTagWriter = KoinTagWriter(codeGenerator,logger)
private val koinConfigChecker = KoinConfigChecker(codeGenerator, logger)

override fun process(resolver: Resolver): List<KSAnnotated> {
initComponents(resolver)

logger.logging("Scan symbols ...")

val invalidSymbols = koinMetaDataScanner.scanSymbols(resolver)
Expand All @@ -48,33 +53,41 @@ class BuilderProcessor(
isDefault = true,
)

logger.logging("Scan metadata ...")
logger.logging("Build metadata ...")
val moduleList = koinMetaDataScanner.scanKoinModules(defaultModule)

logger.logging("Generate code ...")
koinCodeGenerator.generateModules(moduleList, defaultModule, isDefaultModuleActive())

val allModules = moduleList + defaultModule
koinTagWriter.writeAllTags(moduleList, defaultModule)

if (isConfigCheckActive()) {
logger.warn("Koin Configuration Check")
koinConfigVerification.verifyDefinitionDeclarations(moduleList + defaultModule, resolver)
koinConfigVerification.verifyModuleIncludes(moduleList + defaultModule, resolver)
logger.warn("Check Configuration ...")
koinConfigChecker.verifyDefinitionDeclarations(allModules, resolver)
koinConfigChecker.verifyModuleIncludes(allModules, resolver)
}
return emptyList()
}

private fun initComponents(resolver: Resolver) {
koinCodeGenerator.resolver = resolver
koinTagWriter.resolver = resolver
}

private fun isConfigCheckActive(): Boolean {
return options.getOrDefault(KOIN_CONFIG_CHECK.name, "false") == true.toString()
}

//TODO Use Koin 4.0 ViewModel DSL
@Deprecated("use isKoinComposeViewModelActive")
private fun isComposeViewModelActive(): Boolean {
logger.warn("[Deprecated] Please use KOIN_USE_COMPOSE_VIEWMODEL arg")
logger.warn("[Deprecated] 'USE_COMPOSE_VIEWMODEL' arg is deprecated. Please use 'KOIN_USE_COMPOSE_VIEWMODEL'")
return options.getOrDefault(USE_COMPOSE_VIEWMODEL.name, "false") == true.toString()
}

private fun isKoinComposeViewModelActive(): Boolean {
logger.warn("Use Compose ViewModel for @KoinViewModel generation")
logger.warn("Activate Compose ViewModel for @KoinViewModel generation")
return options.getOrDefault(KOIN_USE_COMPOSE_VIEWMODEL.name, "false") == true.toString()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright 2017-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.koin.compiler.generator

import com.google.devtools.ksp.processing.CodeGenerator
import com.google.devtools.ksp.processing.Resolver
import org.koin.compiler.metadata.KoinMetaData

class ClassModuleWriter(
codeGenerator: CodeGenerator,
resolver: Resolver,
module: KoinMetaData.Module
) : ModuleWriter(codeGenerator, resolver, module) {

override val fileName : String = generateModuleFileName(module)
private fun generateModuleFileName(m: KoinMetaData.Module): String {
val extensionName = m.packageName("$")
return "${m.name}Gen${extensionName}"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2017-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.koin.compiler.generator

import com.google.devtools.ksp.processing.CodeGenerator
import com.google.devtools.ksp.processing.Resolver
import org.koin.compiler.metadata.KoinMetaData

class DefaultModuleWriter(
codeGenerator: CodeGenerator,
resolver: Resolver,
defaultModule: KoinMetaData.Module,
generateDefaultModule: Boolean
) : ModuleWriter(codeGenerator, resolver, defaultModule) {

override val fileName : String = "KoinDefault-${defaultModule.hashCode()}"
override val hasExternalDefinitions: Boolean = true
override val generateModuleBody: Boolean = generateDefaultModule

override fun writeModuleFooter() {
writeln(DEFAULT_MODULE_FOOTER)
}
}
Loading
Loading