diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt index 9a45c5c1ce1..706a5e216f4 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt @@ -94,10 +94,12 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : IrEle private val useOptimizedSuperClass = context.state.generateOptimizedCallableReferenceSuperClasses + private val IrClass.isSynthetic + get() = metadata !is MetadataSource.File && metadata !is MetadataSource.Class && metadata !is MetadataSource.Script + private val IrMemberAccessExpression<*>.propertyContainer: IrDeclarationParent get() = if (this is IrLocalDelegatedPropertyReference) - currentClassData?.localPropertyOwner(getter) - ?: throw AssertionError("local property reference before declaration: ${render()}") + findClassOwner() else getter?.owner?.parent ?: field?.owner?.parent ?: error("Property without getter or field: ${dump()}") @@ -106,6 +108,23 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : IrEle private val IrField.fakeGetterSignature: String get() = "${JvmAbi.getterName(name.asString())}()${context.defaultMethodSignatureMapper.mapReturnType(this)}" + private val IrDeclaration.parentsWithSelf: Sequence + get() = generateSequence(this) { it.parent as? IrDeclaration } + + private fun IrLocalDelegatedPropertyReference.findClassOwner(): IrClass { + val originalBeforeInline = originalBeforeInline + if (originalBeforeInline != null) { + require(originalBeforeInline is IrLocalDelegatedPropertyReference) { + "Original for local delegated property ${render()} has another type: ${originalBeforeInline.render()}" + } + return originalBeforeInline.findClassOwner() + } + + val containingClasses = symbol.owner.parentsWithSelf.filterIsInstance() + // Prefer to attach metadata to non-synthetic classes, similarly to how it's done in rememberLocalProperty. + return containingClasses.firstOrNull { !it.isSynthetic } ?: containingClasses.first() + } + private fun IrBuilderWithScope.computeSignatureString(expression: IrMemberAccessExpression<*>): IrExpression { if (expression is IrLocalDelegatedPropertyReference) { // Local delegated properties are stored as a plain list, and the runtime library extracts the index from this string: @@ -213,19 +232,14 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : IrEle val localProperties = mutableListOf() val localPropertyIndices = mutableMapOf() - val isSynthetic = irClass.metadata !is MetadataSource.File && irClass.metadata !is MetadataSource.Class && - irClass.metadata !is MetadataSource.Script fun localPropertyIndex(getter: IrSymbol): Int? = localPropertyIndices[getter] ?: parent?.localPropertyIndex(getter) - fun localPropertyOwner(getter: IrSymbol): IrClass? = - if (getter in localPropertyIndices) irClass else parent?.localPropertyOwner(getter) - fun rememberLocalProperty(property: IrLocalDelegatedProperty) { // Prefer to attach metadata to non-synthetic classes, because it won't be serialized otherwise; // if not possible, though, putting it right here will at least allow non-reflective uses. - val metadataOwner = generateSequence(this) { it.parent }.find { !it.isSynthetic } ?: this + val metadataOwner = generateSequence(this) { it.parent }.find { !it.irClass.isSynthetic } ?: this metadataOwner.localPropertyIndices[property.getter.symbol] = metadataOwner.localProperties.size metadataOwner.localProperties.add(property.symbol) } diff --git a/compiler/testData/codegen/box/reflection/properties/localDelegated/inLambdaInInline.kt b/compiler/testData/codegen/box/reflection/properties/localDelegated/inLambdaInInline.kt index 5a886286bfa..f04ffc79070 100644 --- a/compiler/testData/codegen/box/reflection/properties/localDelegated/inLambdaInInline.kt +++ b/compiler/testData/codegen/box/reflection/properties/localDelegated/inLambdaInInline.kt @@ -1,6 +1,5 @@ // TARGET_BACKEND: JVM // IGNORE_BACKEND: JVM -// IGNORE_INLINER: IR // WITH_REFLECT // FILE: 1.kt package test diff --git a/compiler/testData/codegen/box/reflection/properties/localDelegated/inlineFun.kt b/compiler/testData/codegen/box/reflection/properties/localDelegated/inlineFun.kt index 048a670b03b..74716048087 100644 --- a/compiler/testData/codegen/box/reflection/properties/localDelegated/inlineFun.kt +++ b/compiler/testData/codegen/box/reflection/properties/localDelegated/inlineFun.kt @@ -1,5 +1,4 @@ // TARGET_BACKEND: JVM -// IGNORE_INLINER: IR // WITH_REFLECT import kotlin.reflect.*