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

Unable to create a reified method on Compose-KMP for iOS build #3579

Closed
RodrigoFerreira001 opened this issue Aug 29, 2023 · 5 comments
Closed
Labels
bug Something isn't working duplicate This issue or pull request already exists

Comments

@RodrigoFerreira001
Copy link

RodrigoFerreira001 commented Aug 29, 2023

Describe the bug
A clear and concise description of what the bug is.

Affected platforms
Select one of the platforms below:

  • iOS

Versions

  • Kotlin version*: 1.9.0
  • Compose Multiplatform version*: 1.5.0-beta02
  • OS architecture (x86 or arm64): arm64

To Reproduce
Steps and/or the code snippet to reproduce the behavior:
Create a reified composable function and try to build an iOS app.

Expected behavior
Build successfully

Additional context
Add any other context about the problem here.

Compilation Log

Details

Compilation failed: Generation of stubs for class org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterPublicSymbolImpl is not supported yet

  • Source files:
  • Compiler version: 1.9.0
  • Output kind: FRAMEWORK

error: kotlin.NotImplementedError: Generation of stubs for class org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterPublicSymbolImpl is not supported yet
at org.jetbrains.kotlin.backend.common.linkage.partial.MissingDeclarationStubGenerator.getDeclaration(MissingDeclarationStubGenerator.kt:57)
at org.jetbrains.kotlin.backend.common.linkage.partial.PartialLinkageSupportForLinkerImpl.generateStubsAndPatchUsagesInternal(PartialLinkageSupportForLinkerImpl.kt:72)
at org.jetbrains.kotlin.backend.common.linkage.partial.PartialLinkageSupportForLinkerImpl.generateStubsAndPatchUsages(PartialLinkageSupportForLinkerImpl.kt:62)
at org.jetbrains.kotlin.backend.common.serialization.KotlinIrLinker.postProcess(KotlinIrLinker.kt:231)
at org.jetbrains.kotlin.backend.konan.serialization.KonanIrLinker.postProcess(KonanIrlinker.kt:412)
at org.jetbrains.kotlin.psi2ir.Psi2IrTranslator.generateModuleFragment(Psi2IrTranslator.kt:104)
at org.jetbrains.kotlin.psi2ir.Psi2IrTranslator.generateModuleFragment$default(Psi2IrTranslator.kt:84)
at org.jetbrains.kotlin.backend.konan.PsiToIrKt.psiToIr(PsiToIr.kt:217)
at org.jetbrains.kotlin.backend.konan.driver.phases.PsiToIrKt$PsiToIrPhase$2.invoke(PsiToIr.kt:102)
at org.jetbrains.kotlin.backend.konan.driver.phases.PsiToIrKt$PsiToIrPhase$2.invoke(PsiToIr.kt:97)
at org.jetbrains.kotlin.backend.konan.driver.phases.PhaseBuildersKt$createSimpleNamedCompilerPhase$1.phaseBody(PhaseBuilders.kt:32)
at org.jetbrains.kotlin.backend.common.phaser.SimpleNamedCompilerPhase.phaseBody(CompilerPhase.kt:207)
at org.jetbrains.kotlin.backend.common.phaser.AbstractNamedCompilerPhase.invoke(CompilerPhase.kt:94)
at org.jetbrains.kotlin.backend.konan.driver.PhaseEngine.runPhase(Machinery.kt:139)
at org.jetbrains.kotlin.backend.konan.driver.PhaseEngine.runPhase$default(Machinery.kt:130)
at org.jetbrains.kotlin.backend.konan.driver.phases.TopLevelPhasesKt.runPsiToIr(TopLevelPhases.kt:53)
at org.jetbrains.kotlin.backend.konan.driver.DynamicCompilerDriver.produceObjCFramework(DynamicCompilerDriver.kt:67)
at org.jetbrains.kotlin.backend.konan.driver.DynamicCompilerDriver.access$produceObjCFramework(DynamicCompilerDriver.kt:31)
at org.jetbrains.kotlin.backend.konan.driver.DynamicCompilerDriver$run$1$1$1.invoke(DynamicCompilerDriver.kt:42)
at org.jetbrains.kotlin.backend.konan.driver.DynamicCompilerDriver$run$1$1$1.invoke(DynamicCompilerDriver.kt:36)
at org.jetbrains.kotlin.backend.konan.driver.PhaseEngine$Companion$startTopLevel$topLevelPhase$1.phaseBody(Machinery.kt:98)
at org.jetbrains.kotlin.backend.konan.driver.PhaseEngine$Companion$startTopLevel$topLevelPhase$1.phaseBody(Machinery.kt:92)
at org.jetbrains.kotlin.backend.common.phaser.SimpleNamedCompilerPhase.phaseBody(CompilerPhase.kt:207)
at org.jetbrains.kotlin.backend.common.phaser.AbstractNamedCompilerPhase.invoke(CompilerPhase.kt:94)
at org.jetbrains.kotlin.backend.konan.driver.PhaseEngine$Companion.startTopLevel(Machinery.kt:105)
at org.jetbrains.kotlin.backend.konan.driver.DynamicCompilerDriver.run(DynamicCompilerDriver.kt:36)
at org.jetbrains.kotlin.backend.konan.KonanDriver.run(KonanDriver.kt:78)
at org.jetbrains.kotlin.cli.bc.K2Native.runKonanDriver(K2Native.kt:136)
at org.jetbrains.kotlin.cli.bc.K2Native.doExecute(K2Native.kt:71)
at org.jetbrains.kotlin.cli.bc.K2Native.doExecute(K2Native.kt:37)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:100)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:46)
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:180)
at org.jetbrains.kotlin.cli.bc.K2Native$Companion$mainNoExitWithRenderer$1.invoke(K2Native.kt:173)
at org.jetbrains.kotlin.cli.bc.K2Native$Companion$mainNoExitWithRenderer$1.invoke(K2Native.kt:172)
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.mainNoExitWithRenderer(K2Native.kt:172)
at org.jetbrains.kotlin.cli.bc.K2NativeKt.mainNoExitWithXcodeRenderer(K2Native.kt:191)
at org.jetbrains.kotlin.cli.utilities.MainKt$daemonMainWithXcodeRenderer$1.invoke(main.kt:53)
at org.jetbrains.kotlin.cli.utilities.MainKt$daemonMainWithXcodeRenderer$1.invoke(main.kt:53)
at org.jetbrains.kotlin.cli.utilities.MainKt.mainImpl(main.kt:20)
at org.jetbrains.kotlin.cli.utilities.MainKt.inProcessMain(main.kt:58)
at org.jetbrains.kotlin.cli.utilities.MainKt.daemonMainWithXcodeRenderer(main.kt:53)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at org.jetbrains.kotlin.compilerRunner.KotlinToolRunner.runInProcess(KotlinToolRunner.kt:189)
at org.jetbrains.kotlin.compilerRunner.KotlinToolRunner.run(KotlinToolRunner.kt:132)
at org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink.compile(KotlinNativeLink.kt:364)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
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:242)
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:227)
at org.gradle.api.internal.tasks.execution.TaskExecution.executeActions(TaskExecution.java:210)
at org.gradle.api.internal.tasks.execution.TaskExecution.executeWithPreviousOutputFiles(TaskExecution.java:193)
at org.gradle.api.internal.tasks.execution.TaskExecution.execute(TaskExecution.java:166)
at org.gradle.internal.execution.steps.ExecuteStep.executeInternal(ExecuteStep.java:93)
at org.gradle.internal.execution.steps.ExecuteStep.access$000(ExecuteStep.java:44)
at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:57)
at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:54)
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:54)
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:166)
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.uti

@RodrigoFerreira001 RodrigoFerreira001 added bug Something isn't working submitted labels Aug 29, 2023
@alexzhirkevich
Copy link
Contributor

#3147

@m-sasha
Copy link
Contributor

m-sasha commented Aug 29, 2023

@RodrigoFerreira001 Is the issue with any reified method, or just using T::class that doesn't work? Can you post a short reproducer?

@m-sasha m-sasha added wait for reply Further information is requested and removed submitted labels Aug 29, 2023
@RodrigoFerreira001
Copy link
Author

Hey @m-sasha! Yes, it's a T::class's reified method (In an Android build it works nicely, but in an iOS build it launches the exception on compilation time):

package com.catbit.moovi.core.extensions

import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import com.catbit.moovi.core.providers.LocalNavigationController
import com.catbit.moovi.core.viewmodel.CreationContext
import com.catbit.moovi.core.viewmodel.ViewModel
import com.catbit.moovi.core.viewmodel.ViewModelFactory
import org.koin.compose.getKoin
import org.koin.core.annotation.KoinInternalApi
import org.koin.core.parameter.ParametersHolder
import org.koin.core.parameter.parametersOf
import org.koin.core.qualifier.Qualifier
import org.koin.core.qualifier.StringQualifier
import org.koin.core.scope.Scope

@OptIn(KoinInternalApi::class)
@Composable
inline fun <reified T : ViewModel> getViewModel(
    qualifier: Qualifier? = null,
    parameters: ParametersHolder = parametersOf()
): T {

    val key = T::class.qualifiedName
    val newQualifier = StringQualifier("$key${qualifier?.toString().orEmpty()}")
    val builderBlock = getKoin().get<Scope.(ParametersHolder) -> T>(newQualifier)
    val scope = getKoin().scopeRegistry.rootScope
    val navigationController = LocalNavigationController.current
    val stackEntryId = navigationController.stack.last().id
    val viewModelKey = "$key$stackEntryId"

    val viewModelCreationContext = remember(viewModelKey) {
        ViewModelFactory.getViewModel(
            key = viewModelKey,
            builderBlock = { builderBlock(scope, parameters) }
        ).also {
            navigationController.addStackEntryDestructionObserver(stackEntryId) {
                ViewModelFactory.removeViewModel(viewModelKey)
            }
        }
    }

    LaunchedEffect(viewModelKey) {
        when (viewModelCreationContext.context) {
            CreationContext.Created -> viewModelCreationContext.viewModel.onStart()
            CreationContext.Recovered -> viewModelCreationContext.viewModel.onRecover()
        }
    }

    DisposableEffect(viewModelKey) {
        onDispose {
            viewModelCreationContext.viewModel.onDispose()
        }
    }

    return viewModelCreationContext.viewModel
}

@m-sasha
Copy link
Contributor

m-sasha commented Aug 29, 2023

Ok, then it's indeed the same issue as #3147

@m-sasha m-sasha closed this as completed Aug 29, 2023
@m-sasha m-sasha added duplicate This issue or pull request already exists and removed wait for reply Further information is requested labels Aug 29, 2023
@okushnikov
Copy link

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

4 participants