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

Flow extension functions not fully supported #9

Closed
ubuntudroid opened this issue Sep 18, 2023 · 15 comments
Closed

Flow extension functions not fully supported #9

ubuntudroid opened this issue Sep 18, 2023 · 15 comments

Comments

@ubuntudroid
Copy link

ubuntudroid commented Sep 18, 2023

I have a Kotlin Flow extension function that basically converts a Flow to a simple return value based on the state of a result wrapper object:

suspend fun <T> Flow<Resultat<T>>.firstAfterLoading(): Resultat<T> = first { it.isSuccess || it.isFailure }

However, this results in a compilation exception:

Details

Showing All Messages
e: Compilation failed: The /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc command returned non-zero exit code: 1.
output:
      __Skie.file__shared____SkieSuspendWrappersKt.Skie_Suspend__1__firstAfterLoading(extensionReceiver:suspendHandler:)(this, $0)
                                                                                                                         ^
                                                                                                                              as! Kotlinx_coroutines_coreFlow

 * Source files: 
 * Compiler version info: Konan: 1.8.10 / Kotlin: 1.8.10
 * Output kind: FRAMEWORK

e: java.lang.IllegalStateException: The /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc command returned non-zero exit code: 1.
output:
/Users/ubuntudroid/projects/github/project/shared/build/skie/podReleaseFramework/iosX64/swift/generated/my.package.name.util.firstAfterLoading.swift:6:122: argument type 'SkieSwiftFlow<Resultat<AnyObject>>' does not conform to expected type 'Kotlinx_coroutines_coreFlow'
      __Skie.file__shared____SkieSuspendWrappersKt.Skie_Suspend__1__firstAfterLoading(extensionReceiver:suspendHandler:)(this, $0)
                                                                                                                         ^
                                                                                                                              as! Kotlinx_coroutines_coreFlow
	at co.touchlab.skie.util.Command.handleExitCode(Command.kt:102)
	at co.touchlab.skie.util.Command.execute(Command.kt:85)
	at co.touchlab.skie.util.Command.execute$default(Command.kt:57)
	at co.touchlab.skie.api.phases.CompileSwiftPhase.callSwiftCompiler(CompileSwiftPhase.kt:83)
	at co.touchlab.skie.api.phases.CompileSwiftPhase.execute(CompileSwiftPhase.kt:35)
	at co.touchlab.skie.plugin.SkieLinkingPhaseScheduler$runLinkingPhases$2$1.invoke(SkieLinkingPhaseScheduler.kt:90)
	at co.touchlab.skie.plugin.SkieLinkingPhaseScheduler$runLinkingPhases$2$1.invoke(SkieLinkingPhaseScheduler.kt:89)
	at co.touchlab.skie.analytics.performance.SkiePerformanceAnalytics$Producer.log(SkiePerformanceAnalytics.kt:31)
	at co.touchlab.skie.plugin.SkieLinkingPhaseScheduler.runLinkingPhases(SkieLinkingPhaseScheduler.kt:89)
	at co.touchlab.skie.plugin.SwiftLinkCompilePhase.process(SwiftLinkCompilePhase.kt:69)
	at co.touchlab.skie.plugin.interceptors.ObjectFilesPhaseInterceptor.runSwiftLinkCompilePhase(ObjectFilesPhaseInterceptor.kt:46)
	at co.touchlab.skie.plugin.interceptors.ObjectFilesPhaseInterceptor.intercept(ObjectFilesPhaseInterceptor.kt:26)
	at co.touchlab.skie.plugin.interceptors.ObjectFilesPhaseInterceptor.intercept(ObjectFilesPhaseInterceptor.kt:17)k
	at co.touchlab.skie.plugin.intercept.ErasedPhaseInterceptorChain$chainedInterceptors$2$erasedInterceptors$1$1.invoke(ErasedPhaseInterceptorChain.kt:12)
	at co.touchlab.skie.plugin.intercept.ErasedPhaseInterceptorChain$chainedInterceptors$2$erasedInterceptors$1$1.invoke(ErasedPhaseInterceptorChain.kt:12)
	at co.touchlab.skie.plugin.intercept.ErasedPhaseInterceptorChain.invoke(ErasedPhaseInterceptorChain.kt:19)
	at co.touchlab.skie.plugin.intercept.ErasedPhaseInterceptorChain.invoke(ErasedPhaseInterceptorChain.kt:6)
	at co.touchlab.skie.plugin.intercept.InterceptedSameTypeCompilerPhase.invoke(InterceptedSameTypeCompilerPhase.kt:18)
	at org.jetbrains.kotlin.backend.common.phaser.NamedCompilerPhase.invoke(CompilerPhase.kt:96)
	at org.jetbrains.kotlin.backend.common.phaser.CompositePhase.invoke(PhaseBuilders.kt:29)
	at org.jetbrains.kotlin.backend.common.phaser.NamedCompilerPhase.invoke(CompilerPhase.kt:96)
	at org.jetbrains.kotlin.backend.common.phaser.CompilerPhaseKt.invokeToplevel(CompilerPhase.kt:43)
	at org.jetbrains.kotlin.backend.konan.KonanDriverKt.runTopLevelPhases(KonanDriver.kt:102)
	at org.jetbrains.kotlin.backend.konan.KonanDriverKt.access$runTopLevelPhases(KonanDriver.kt:1)
	at org.jetbrains.kotlin.backend.konan.KonanDriver.runTopLevelPhases(KonanDriver.kt:63)
	at org.jetbrains.kotlin.backend.konan.KonanDriver.run(KonanDriver.kt:43)
	at org.jetbrains.kotlin.cli.bc.K2Native.doExecute(K2Native.kt:92)
	at org.jetbrains.kotlin.cli.bc.K2Native.doExecute(K2Native.kt:38)
	at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:101)
	at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:47)
	at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:101)
	at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:79)
	at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:43)
	at org.jetbrains.kotlin.cli.common.CLITool$Companion.doMainNoExit(CLITool.kt:179)
	at org.jetbrains.kotlin.cli.bc.K2Native$Companion$mainNoExitWithGradleRenderer$1.invoke(K2Native.kt:399)
	at org.jetbrains.kotlin.cli.bc.K2Native$Companion$mainNoExitWithGradleRenderer$1.invoke(K2Native.kt:398)
	at org.jetbrains.kotlin.util.UtilKt.profileIf(Util.kt:22)
	at org.jetbrains.kotlin.util.UtilKt.profile(Util.kt:16)
	at org.jetbrains.kotlin.cli.bc.K2Native$Companion.mainNoExitWithGradleRenderer(K2Native.kt:398)
	at org.jetbrains.kotlin.cli.bc.K2NativeKt.mainNoExitWithGradleRenderer(K2Native.kt:635)
	at org.jetbrains.kotlin.cli.utilities.MainKt$daemonMain$1$1.invoke(main.kt:70)
	at org.jetbrains.kotlin.cli.utilities.MainKt$daemonMain$1$1.invoke(main.kt:70)
	at org.jetbrains.kotlin.cli.utilities.MainKt.mainImpl(main.kt:19)
	at org.jetbrains.kotlin.cli.utilities.MainKt.daemonMain(main.kt:70)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:578)
	at org.jetbrains.kotlin.compilerRunner.KotlinToolRunner.runInProcess(KotlinToolRunner.kt:191)
	at org.jetbrains.kotlin.compilerRunner.KotlinToolRunner.run(KotlinToolRunner.kt:133)
	at org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink.compile(KotlinNativeLink.kt:327)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:578)
	at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:125)
	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:58)
	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:51)
	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:29)
	at org.gradle.api.internal.tasks.execution.TaskExecution$3.run(TaskExecution.java:248)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:68)
	at org.gradle.api.internal.tasks.execution.TaskExecution.executeAction(TaskExecution.java:233)
	at org.gradle.api.internal.tasks.execution.TaskExecution.executeActions(TaskExecution.java:216)
	at org.gradle.api.internal.tasks.execution.TaskExecution.executeWithPreviousOutputFiles(TaskExecution.java:199)
	at org.gradle.api.internal.tasks.execution.TaskExecution.execute(TaskExecution.java:166)
	at org.gradle.internal.execution.steps.ExecuteStep.executeInternal(ExecuteStep.java:105)
	at org.gradle.internal.execution.steps.ExecuteStep.access$000(ExecuteStep.java:44)
	at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:59)
	at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:56)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
	at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:56)
	at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:44)
	at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:67)
	at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:37)
	at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:41)
	at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:74)
	at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:55)
	at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:50)
	at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:28)
	at org.gradle.internal.execution.steps.CaptureStateAfterExecutionStep.executeDelegateBroadcastingChanges(CaptureStateAfterExecutionStep.java:100)
	at org.gradle.internal.execution.steps.CaptureStateAfterExecutionStep.execute(CaptureStateAfterExecutionStep.java:72)
	at org.gradle.internal.execution.steps.CaptureStateAfterExecutionStep.execute(CaptureStateAfterExecutionStep.java:50)
	at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:40)
	at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:29)
	at org.gradle.internal.execution.steps.BuildCacheStep.executeWithoutCache(BuildCacheStep.java:179)
	at org.gradle.internal.execution.steps.BuildCacheStep.lambda$execute$1(BuildCacheStep.java:70)
	at org.gradle.internal.Either$Right.fold(Either.java:175)
	at org.gradle.internal.execution.caching.CachingState.fold(CachingState.java:59)
	at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:68)
	at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:46)
	at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:36)
	at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:25)
	at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:36)
	at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:22)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:91)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$2(SkipUpToDateStep.java:55)
	at java.base/java.util.Optional.orElseGet(Optional.java:364)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:55)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:37)
	at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:65)
	at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:36)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:37)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:27)
	at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:77)
	at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:38)
	at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:94)
	at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:49)
	at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:71)
	at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:45)
	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.executeWithNonEmptySources(SkipEmptyWorkStep.java:177)
	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:86)
	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:53)
	at org.gradle.internal.execution.steps.RemoveUntrackedExecutionStateStep.execute(RemoveUntrackedExecutionStateStep.java:32)
	at org.gradle.internal.execution.steps.RemoveUntrackedExecutionStateStep.execute(RemoveUntrackedExecutionStateStep.java:21)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:38)
	at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:36)
	at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:23)
	at org.gradle.internal.execution.steps.CleanupStaleOutputsStep.execute(CleanupStaleOutputsStep.java:75)
	at org.gradle.internal.execution.steps.CleanupStaleOutputsStep.execute(CleanupStaleOutputsStep.java:41)
	at org.gradle.internal.execution.steps.AssignWorkspaceStep.lambda$execute$0(AssignWorkspaceStep.java:32)
	at org.gradle.api.internal.tasks.execution.TaskExecution$4.withWorkspace(TaskExecution.java:293)
	at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:30)
	at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:21)
	at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:37)
	at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:27)
	at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:47)
	at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:34)
	at org.gradle.internal.execution.impl.DefaultExecutionEngine$1.execute(DefaultExecutionEngine.java:64)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:146)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:135)
	at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
	at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51)
	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:74)
	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
	at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:42)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:337)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:324)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:317)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:303)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:463)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:380)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
	at java.base/java.lang.Thread.run(Thread.java:1623)

@ubuntudroid ubuntudroid changed the title Flow extensions functions not fully supported Flow extension functions not fully supported Sep 18, 2023
@FilipDolnik
Copy link
Member

I wasn't able to reproduce the issue locally. What version of SKIE, Kotlin, and Xcode do you use?

@ubuntudroid
Copy link
Author

SKIE: 0.4.20
Kotlin: 1.8.10
Xcode: 14.3.1

Removing that extension function makes the error go away, so it seems to be really caused by this line.

We can do a screensharing session if it helps. Unfortunately the project itself isn't open source.

@FilipDolnik
Copy link
Member

I was able to reproduce the issue by disabling Flow support for the suspend function. Do you also have the the flows disabled? (probably in the Gradle config)

@ubuntudroid
Copy link
Author

It is enabled, but only for my shared module.

Just an idea: the Resultat class is actually a sealed class from a library with the following signature:

public sealed class Resultat<out T>

Could it be that because that sealed class isn't treated by the SKIE gradle plugin the compilation issue caused?

@ubuntudroid
Copy link
Author

ubuntudroid commented Sep 18, 2023

Hm, no, enabling SKIE enum and sealed class handling and/or flow/suspend handling for the Resultat package doesn't improve the situation. Must be something else. 🤔

@ubuntudroid
Copy link
Author

This is what SKIE generates:

public extension __Skie.file__Project_shared__ResultatFlowExtensionsKt {

  @available(iOS 13, macOS 10.15, watchOS 6, tvOS 13, * )
  static func firstAfterLoading(_ this: __Skie.swift__SkieSwiftFlow<__Skie.class__fr_haan_resultat_resultat__fr_haan_resultat_Resultat<Swift.AnyObject>>) async throws -> __Skie.class__fr_haan_resultat_resultat__fr_haan_resultat_Resultat<Swift.AnyObject> {
    return try await SwiftCoroutineDispatcher.dispatch {
      __Skie.file__shared____SkieSuspendWrappersKt.Skie_Suspend__1__firstAfterLoading(extensionReceiver:suspendHandler:)(this, $0)
    }
  }

}

@FilipDolnik
Copy link
Member

FilipDolnik commented Sep 18, 2023

It is enabled, but only for my shared module.

And is the firstAfterLoading in that shared module?

The generated code is the same as the one I got. What I think causes the problem is that the firstAfterLoading extension receiver is not converted by SKIE to the SwiftFlow because the Flow interop is not enabled for the function. However, the generated code does assume that it is converted (which is a bug).

@ubuntudroid
Copy link
Author

Yes, firstAfterLoading is part of the shared module so it should also benefit from Flow interop.

@FilipDolnik
Copy link
Member

Ok, we need to look at the content of the apinotes file. In the skie build directory (the one that contains the swift/generated directory) is a file swift-compiler/apinotes/$frameworkName.apinotes.

In that file, there should be an entry for the generated function (search for Skie_Suspend__1__firstAfterLoading). Then please send me the block of lines that describe this function. The block should start with - Selector: "Skie_Suspend__1__firstAfterLoadingExtensionReceiver:suspendHandler:" and it ends with another - Selector if there is any (it should be about 9-10 lines)

@ubuntudroid
Copy link
Author

Yes, indeed, there is a selector:

  - Selector: "Skie_Suspend__1__firstAfterLoadingExtensionReceiver:suspendHandler:"
    MethodKind: "Class"
    SwiftName: "Skie_Suspend__1__firstAfterLoading(extensionReceiver:suspendHandler:)"
    SwiftPrivate: true
    ResultType: "void"
    Parameters:
    - Position: 0
      Type: "id<SharedKotlinx_coroutines_coreFlow> _Nonnull "
    - Position: 1
      Type: "SharedSkie_SuspendHandler *_Nonnull "

@FilipDolnik
Copy link
Member

Yeah, the extension receiver is indeed not mapped correctly. It should look like this:

Parameters:
    - Position: 0
      Type: "SharedSkieKotlinFlow<SharedResultat<id> *> *_Nonnull "

Try adding the following annotation to your function:

@co.touchlab.skie.configuration.annotations.FlowInterop.Enabled
suspend fun <T> Flow<Resultat<T>>.firstAfterLoading(): Resultat<T> = first { it.isSuccess || it.isFailure }

You might need to add the following dependency to the module:

implementation("co.touchlab.skie:configuration-annotations:0.4.20")

@ubuntudroid
Copy link
Author

That unfortunately didn't do anything. Anything else I can try?

@FilipDolnik
Copy link
Member

For now, add the following group to your gradle configuration (after all your groups):

group("co.touchlab.skie.generated") {
      FlowInterop.Enabled(true)
}

(You can remove the annotations, they are not needed.)

I think I now have a good enough understanding of both of those issues and know how to fix them. So I will try that and let you know if I need further assistance with debugging.

@ubuntudroid
Copy link
Author

That fixes it indeed! Thanks for providing the workaround! 🙏

@FilipDolnik
Copy link
Member

Fixed in 0.5.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants