dokka icon indicating copy to clipboard operation
dokka copied to clipboard

[K2] KMP: Extension function miss platform tab for shared source set with one target

Open atyrin opened this issue 1 year ago • 3 comments

See the reproducer attached. Case is taken from okhttp

ModuleA: JVM + iosX64

// commonMain
expect interface Call

// jvmMain
actual interface Call

//nativeMain
actual interface Call

ModuleB: JVM + iosX64 Depends on ModuleA

// commonMain
expect fun Call.dokka()

// jvmMain
actual fun Call.dokka(){}

//nativeMain
actual fun Call.dokka(){}

For K2 the dokka() extension miss native tab image

Installation

  • Dokka version: 1.9.20

Parent: https://github.com/Kotlin/dokka/issues/3328 dokka-repros.zip

atyrin avatar Nov 29 '23 17:11 atyrin

It is reproduced for linuxX64 target on Ubuntu.

~~It is blocked by https://youtrack.jetbrains.com/issue/KT-64321/Analysis-API-Extension-functions-are-missed-for-shared-source-set-with-one-target~~

Update 14.05: it is still reproducible with gradle :module1:dokkaHtml

vmishenev avatar Dec 13 '23 21:12 vmishenev

First of all, the issue is not only about extension functions, but overall about resolving types from other modules when there are intermediate source sets for one target. In such cases KGP will not create tasks to compile those shared source sets to metadata and so no compiler invocation will be done for such source sets. So for module there will be produced: jvm.jar, iosx64.klib and metadata for commonMain only. If we add additional native target, like iosArm64 , then KGP will create task to compile nativeMain (and also appleMain and iosMain, but they are empty, so no task will be executed and no metadata produced) to metadata and so there will be following artefacts: jvm.jar, iosx64.klib and metadata for commonMain and nativeMain. In this case, all declarations will be resolved correctly.

Here are example for top-level properties/functions. Those with Native suffix are declared in nativeMain sourceSet, other declared in commonMain (as expect) and actualised in jvmMain and nativeMain: image image Here are the same properties/functions declared inside Wrapper class declared in commonMain (as expect) and actualised in jvmMain and nativeMain: image And here are the same properties/functions declared inside WrapperNative class declared in nativeMain sourceSet: image

As you can see here in some places Call is even resolved (and native tab is shown): return types of functions/properties declared in common. But all declarations which are only in native source set (no expect/actual) - are unresolved.

I will mention it one time, the issues exist only when there are intermediate source sets with ONE target.

TBD if the issue on Analysis API side or our side.

whyoleg avatar May 22 '24 13:05 whyoleg

To sum up,

  • The both K1 and K2 do not see declarations from shared/intermediate source sets with a single target at all (see #3122)
  • Dokka K1 can show actual extensions when a receiver has only its expect class in klib
  • Dokka K2 does not see actual extensions when a receiver has only its expect class in klib. (In K2, the receiver is unresolved, but in K1 is resolved)

The root of the problem

From Oleg's investigation above:

With two targets: image vs with a single one image

KGP already generates klib - iosx64.klib, but the Dokka Gradle Plugin does not pass it into a Dokka native source set in the case of a single target. This klib is enough to resolve all symbols from the shared/intermediate source set in K2.

Notice in my example with a single target, the linuxX64 source set has the linuxX64.klib, but does not a source root. Opposite, the native source set has needed source roots, but no klibs (also platform klibs?!).

vmishenev avatar May 23 '24 12:05 vmishenev