yandex / scout

A fast and safe manual dependency injector for Kotlin and Android.
Apache License 2.0
102 stars 4 forks source link

Support KMP #14

Open RecodeLiner opened 8 months ago

RecodeLiner commented 8 months ago

Hello, in search of fast non-code-generative di frameworks I came across your rather progressive (except for the lack of a universal get) library, but as I noticed it lacks support for multiplatform, which seems to be standard for modern kotlin libraries, as I see there is support for desktop (jvm) and android, but iosTarget is unfortunately missing, although at a quick glance everything is already prepared, all procedures go to the final recompilation in objective C.

vdshb commented 8 months ago

I also think, that multiplatform support is a missing part of this promising DI library. I believe this set of targets is a good foundation (.kts-like config example for 1.9.20):

jvm {
    jvmToolchain(11)
    compilations.all {
        kotlinOptions.jvmTarget = "11"
    }
    testRuns["test"].executionTask.configure {
        useJUnitPlatform()
    }
}
js {
    binaries.library()
    browser()
    nodejs()
}
wasmJs { // might be postponed as it's experimental. But better chose test libraries which will support it at some point.
    binaries.library()
    browser()
    nodejs()
}
mingwX64()
val hostOs = System.getProperty("os.name")
if (hostOs == "Linux" || hostOs == "Mac OS X") {
    linuxX64()
    linuxArm64()
}
if (hostOs == "Mac OS X") {
    macosX64()
    macosArm64()
    iosX64()
    iosArm64()
    iosSimulatorArm64()
    tvosX64()
    tvosArm64()
    tvosSimulatorArm64()
    watchosX64()
    watchosArm32()
    watchosArm64()
    watchosSimulatorArm64()
    watchosDeviceArm64()
}

The only JVM-only dependencies I see after brief investigation: JUnit and assertj. My suggestion would be using kotlin-test and kotest-assertions, but kotest team is not in a hurry to support wasm (https://github.com/kotest/kotest/issues/3598) (which is experimental, but steadily becoming the main browser target for KMP). It might be reasonable to chose another assertions alternative or wait a little to see what will going on in this field.

Multiplatform concurrency and multithreading approaches must be adopted as well. Probably with coroutines (I suppose, until you want to start new threads you don't need it), atomicFu (it works as a compiler plugin so it's not an additional dependency for scout) and @Volatile. But I can see quiet small amount of code related to concurrency and multithreading in scout, which is great. At the same time performance is the priority for scout team, so it might take some effort to migrate without performance loose. This part might go smooth though by simply swapping java atomics with kotlinx atomics. JS target might be challenging as well, as it's a single-thread target. It might go smooth as well though. Can't say without try or deeper investigations.

acelost commented 7 months ago

The main problem is with validator as it uses reflective approach. We are trying to migrate validation process from reflection without devexp degradation. The simplest way is to validate only jvm target but we want to make more native solution

antailyaqwer commented 7 months ago

The main problem is with validator as it uses reflective approach. We are trying to migrate validation process from reflection without devexp degradation. The simplest way is to validate only jvm target but we want to make more native solution

That's a good intention, but what about step by step developing :) ? At least jvm validation is fine

vdshb commented 7 months ago

we want to make more native solution

Perfect solution might be not that easy to achive yet. Compiler plugins are limited by compilation module, so you'll have to accept this limitation (I believe it's a false path) or work with klib/jar directly. Good news klib just became stable in 1.9.20 and jar parse/instrumentation libraries are mature. Bad news there are no klib-instrumentation/parsing libraries as I aware of. Good news, It looks like they have all the linkage metadata in klib/linkdata as a set of ProtoBuf(!) files. So it might be not that hard to write a library that parses the signatures of available classes. If this info is enough to validator, it looks acievable, but it's still quiet a harness need to be written to make it work.

vdshb commented 6 months ago

@acelost , could you publish "simplest solution" in separated branch for early adopters? If there is anything to show. I believe it would be valuable as is without any guarantees with small to medium devexp degradation.