JetBrains / compose-multiplatform

Compose Multiplatform, a modern UI framework for Kotlin that makes building performant and beautiful user interfaces easy and enjoyable.
https://jetbrains.com/lp/compose-multiplatform
Apache License 2.0
15.91k stars 1.16k forks source link

Anonymous object with composable function from interface crashes compiler when targeting JS #2612

Open JakeWharton opened 1 year ago

JakeWharton commented 1 year ago

Jetpack Compose version:

Kotlin version: 1.7.20

Reproducing project attached to https://issuetracker.google.com/issues/264799026

Steps to Reproduce or Code Sample to Reproduce:

  1. Unzip project
  2. ./gradlew assemble
  3. Sorrow

The offending code:

interface Ui {
  @Composable fun Show()
}

private class SomePrivateClass {
  fun stuff(): Ui = object : Ui {
    @Composable
    override fun Show() {
    }
  }
}

Stack trace (if applicable):

Caused by: java.lang.IllegalStateException: File expected to be not null (com.example, SomePrivateClass.stuff)
        at org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureBuilder.build(IdSignatureBuilder.kt:61)
        at org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureBuilder.buildSignature(IdSignatureBuilder.kt:114)
        at org.jetbrains.kotlin.backend.common.serialization.signature.PublicIdSignatureComputer.composePublicIdSignature(IdSignatureSerializer.kt:37)
        at org.jetbrains.kotlin.backend.common.serialization.GlobalDeclarationTable.computeSignatureByDeclaration(DeclarationTable.kt:48)
        at org.jetbrains.kotlin.backend.common.serialization.DeclarationTable.computeSignatureByDeclaration(DeclarationTable.kt:83)
        at org.jetbrains.kotlin.backend.common.serialization.DeclarationTable.signatureByDeclaration(DeclarationTable.kt:92)
        at org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer.composeContainerIdSignature(IdSignatureSerializer.kt:235)
        at org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer.access$composeContainerIdSignature(IdSignatureSerializer.kt:205)
        at org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer$composeFileLocalIdSignature$2.invoke(IdSignatureSerializer.kt:280)
        at org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer$composeFileLocalIdSignature$2.invoke(IdSignatureSerializer.kt:242)
        at org.jetbrains.kotlin.backend.common.serialization.DeclarationTable.privateDeclarationSignature(DeclarationTable.kt:88)
        at org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer.composeFileLocalIdSignature(IdSignatureSerializer.kt:242)
        at org.jetbrains.kotlin.backend.common.serialization.DeclarationTable.allocateIndexedSignature(DeclarationTable.kt:76)
        at org.jetbrains.kotlin.backend.common.serialization.DeclarationTable.computeSignatureByDeclaration(DeclarationTable.kt:82)
        at org.jetbrains.kotlin.backend.common.serialization.DeclarationTable.signatureByDeclaration(DeclarationTable.kt:92)
        at org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer.composeContainerIdSignature(IdSignatureSerializer.kt:235)
        at org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer.access$composeContainerIdSignature(IdSignatureSerializer.kt:205)
        at org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer$composeFileLocalIdSignature$2.invoke(IdSignatureSerializer.kt:255)
        at org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer$composeFileLocalIdSignature$2.invoke(IdSignatureSerializer.kt:242)
        at org.jetbrains.kotlin.backend.common.serialization.DeclarationTable.privateDeclarationSignature(DeclarationTable.kt:88)
        at org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer.composeFileLocalIdSignature(IdSignatureSerializer.kt:242)
        at org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer.composeSignatureForDeclaration(IdSignatureSerializer.kt:222)
        at androidx.compose.compiler.plugins.kotlin.lower.decoys.DecoyTransformBase$DefaultImpls.getSignatureId(DecoyTransformBase.kt:59)
        at androidx.compose.compiler.plugins.kotlin.lower.decoys.AbstractDecoysLowering.getSignatureId(AbstractDecoysLowering.kt:38)
        at androidx.compose.compiler.plugins.kotlin.lower.decoys.CreateDecoysTransformer.copyWithName(CreateDecoysTransformer.kt:216)
        at androidx.compose.compiler.plugins.kotlin.lower.decoys.CreateDecoysTransformer.copyWithName$default(CreateDecoysTransformer.kt:168)
        at androidx.compose.compiler.plugins.kotlin.lower.decoys.CreateDecoysTransformer.visitSimpleFunction(CreateDecoysTransformer.kt:129)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitSimpleFunction(IrElementTransformerVoid.kt:73)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitSimpleFunction(IrElementTransformerVoid.kt:24)
        at org.jetbrains.kotlin.ir.declarations.IrSimpleFunction.accept(IrSimpleFunction.kt:36)
        at org.jetbrains.kotlin.ir.IrElementBase.transform(IrElementBase.kt:24)
        at org.jetbrains.kotlin.ir.util.TransformKt.transformInPlace(transform.kt:35)
        at org.jetbrains.kotlin.ir.declarations.IrClass.transformChildren(IrClass.kt:74)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitDeclaration(IrElementTransformerVoid.kt:57)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitClass(IrElementTransformerVoid.kt:66)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitClass(IrElementTransformerVoid.kt:67)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitClass(IrElementTransformerVoid.kt:24)
        at org.jetbrains.kotlin.ir.declarations.IrClass.accept(IrClass.kt:64)
        at org.jetbrains.kotlin.ir.IrElementBase.transform(IrElementBase.kt:24)
        at org.jetbrains.kotlin.ir.util.TransformKt.transformInPlace(transform.kt:35)
        at org.jetbrains.kotlin.ir.expressions.IrContainerExpression.transformChildren(IrContainerExpression.kt:32)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitExpression(IrElementTransformerVoid.kt:131)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitContainerExpression(IrElementTransformerVoid.kt:166)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitBlock(IrElementTransformerVoid.kt:169)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitBlock(IrElementTransformerVoid.kt:170)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitBlock(IrElementTransformerVoid.kt:24)
        at org.jetbrains.kotlin.ir.expressions.IrBlock.accept(IrBlock.kt:22)
        at org.jetbrains.kotlin.ir.expressions.IrExpression.transform(IrExpression.kt:28)
        at org.jetbrains.kotlin.ir.expressions.IrReturn.transformChildren(IrReturn.kt:32)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitExpression(IrElementTransformerVoid.kt:131)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitReturn(IrElementTransformerVoid.kt:308)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitReturn(IrElementTransformerVoid.kt:309)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitReturn(IrElementTransformerVoid.kt:24)
        at org.jetbrains.kotlin.ir.expressions.IrReturn.accept(IrReturn.kt:25)
        at org.jetbrains.kotlin.ir.expressions.IrExpression.transform(IrExpression.kt:28)
        at org.jetbrains.kotlin.ir.expressions.IrExpression.transform(IrExpression.kt:21)
        at org.jetbrains.kotlin.ir.util.TransformKt.transformInPlace(transform.kt:35)
        at org.jetbrains.kotlin.ir.expressions.IrBlockBody.transformChildren(IrBlockBody.kt:31)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitBody(IrElementTransformerVoid.kt:108)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitBlockBody(IrElementTransformerVoid.kt:117)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitBlockBody(IrElementTransformerVoid.kt:118)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitBlockBody(IrElementTransformerVoid.kt:24)
        at org.jetbrains.kotlin.ir.expressions.IrBlockBody.accept(IrBlockBody.kt:24)
        at org.jetbrains.kotlin.ir.expressions.IrBody.transform(IrBody.kt:21)
        at org.jetbrains.kotlin.ir.declarations.IrFunction.transformChildren(IrFunction.kt:61)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitDeclaration(IrElementTransformerVoid.kt:57)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitFunction(IrElementTransformerVoid.kt:69)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitSimpleFunction(IrElementTransformerVoid.kt:72)
        at androidx.compose.compiler.plugins.kotlin.lower.decoys.CreateDecoysTransformer.visitSimpleFunction(CreateDecoysTransformer.kt:124)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitSimpleFunction(IrElementTransformerVoid.kt:73)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitSimpleFunction(IrElementTransformerVoid.kt:24)
        at org.jetbrains.kotlin.ir.declarations.IrSimpleFunction.accept(IrSimpleFunction.kt:36)
        at org.jetbrains.kotlin.ir.IrElementBase.transform(IrElementBase.kt:24)
        at org.jetbrains.kotlin.ir.util.TransformKt.transformInPlace(transform.kt:35)
        at org.jetbrains.kotlin.ir.declarations.IrClass.transformChildren(IrClass.kt:74)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitDeclaration(IrElementTransformerVoid.kt:57)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitClass(IrElementTransformerVoid.kt:66)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitClass(IrElementTransformerVoid.kt:67)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitClass(IrElementTransformerVoid.kt:24)
        at org.jetbrains.kotlin.ir.declarations.IrClass.accept(IrClass.kt:64)
        at org.jetbrains.kotlin.ir.IrElementBase.transform(IrElementBase.kt:24)
        at org.jetbrains.kotlin.ir.util.TransformKt.transformInPlace(transform.kt:35)
        at org.jetbrains.kotlin.ir.declarations.IrFile.transformChildren(IrFile.kt:40)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitPackageFragment(IrElementTransformerVoid.kt:41)
        at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitFile(IrElementTransformerVoid.kt:47)
        at androidx.compose.compiler.plugins.kotlin.lower.decoys.AbstractDecoysLowering.access$visitFile$s780614737(AbstractDecoysLowering.kt:38)
        at androidx.compose.compiler.plugins.kotlin.lower.decoys.AbstractDecoysLowering$visitFile$1$1.invoke(AbstractDecoysLowering.kt:56)
        at androidx.compose.compiler.plugins.kotlin.lower.decoys.AbstractDecoysLowering$visitFile$1$1.invoke(AbstractDecoysLowering.kt:55)
        at org.jetbrains.kotlin.backend.common.serialization.signature.PublicIdSignatureComputer.inFile(IdSignatureSerializer.kt:45)
        at org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer.inFile(IdSignatureSerializer.kt:229)
        at androidx.compose.compiler.plugins.kotlin.lower.decoys.AbstractDecoysLowering.visitFile(AbstractDecoysLowering.kt:55)
        ... 50 more

I forgot to check if the fact that the enclosing class was private was a factor or not, but in my case it was embedded in a private class so that's what I replicated in the reproducer.

Filing issue upstream since you all maintain the JS & native bits of the compiler.

okushnikov commented 2 weeks ago

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