Skip to content

Commit a6e45f9

Browse files
committed
Find correct class owner for inlined local delegated properties
Note that call-site class has no metadata for inlined local delegated properties. Thus, for an inlined local delegated property we should obtain declaration-site class as owner - otherwise, the corresponding `PropertyReference` will have an owner without property metadata.
1 parent d6d1ed6 commit a6e45f9

File tree

3 files changed

+22
-10
lines changed

3 files changed

+22
-10
lines changed

compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,12 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : IrEle
9494
private val useOptimizedSuperClass =
9595
context.state.generateOptimizedCallableReferenceSuperClasses
9696

97+
private val IrClass.isSynthetic
98+
get() = metadata !is MetadataSource.File && metadata !is MetadataSource.Class && metadata !is MetadataSource.Script
99+
97100
private val IrMemberAccessExpression<*>.propertyContainer: IrDeclarationParent
98101
get() = if (this is IrLocalDelegatedPropertyReference)
99-
currentClassData?.localPropertyOwner(getter)
100-
?: throw AssertionError("local property reference before declaration: ${render()}")
102+
findClassOwner()
101103
else
102104
getter?.owner?.parent ?: field?.owner?.parent ?: error("Property without getter or field: ${dump()}")
103105

@@ -106,6 +108,23 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : IrEle
106108
private val IrField.fakeGetterSignature: String
107109
get() = "${JvmAbi.getterName(name.asString())}()${context.defaultMethodSignatureMapper.mapReturnType(this)}"
108110

111+
private val IrDeclaration.parentsWithSelf: Sequence<IrDeclaration>
112+
get() = generateSequence(this) { it.parent as? IrDeclaration }
113+
114+
private fun IrLocalDelegatedPropertyReference.findClassOwner(): IrClass {
115+
val originalBeforeInline = originalBeforeInline
116+
if (originalBeforeInline != null) {
117+
require(originalBeforeInline is IrLocalDelegatedPropertyReference) {
118+
"Original for local delegated property ${render()} has another type: ${originalBeforeInline.render()}"
119+
}
120+
return originalBeforeInline.findClassOwner()
121+
}
122+
123+
val containingClasses = symbol.owner.parentsWithSelf.filterIsInstance<IrClass>()
124+
// Prefer to attach metadata to non-synthetic classes, similarly to how it's done in rememberLocalProperty.
125+
return containingClasses.firstOrNull { !it.isSynthetic } ?: containingClasses.first()
126+
}
127+
109128
private fun IrBuilderWithScope.computeSignatureString(expression: IrMemberAccessExpression<*>): IrExpression {
110129
if (expression is IrLocalDelegatedPropertyReference) {
111130
// 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
213232

214233
val localProperties = mutableListOf<IrLocalDelegatedPropertySymbol>()
215234
val localPropertyIndices = mutableMapOf<IrSymbol, Int>()
216-
val isSynthetic = irClass.metadata !is MetadataSource.File && irClass.metadata !is MetadataSource.Class &&
217-
irClass.metadata !is MetadataSource.Script
218235

219236
fun localPropertyIndex(getter: IrSymbol): Int? =
220237
localPropertyIndices[getter] ?: parent?.localPropertyIndex(getter)
221238

222-
fun localPropertyOwner(getter: IrSymbol): IrClass? =
223-
if (getter in localPropertyIndices) irClass else parent?.localPropertyOwner(getter)
224-
225239
fun rememberLocalProperty(property: IrLocalDelegatedProperty) {
226240
// Prefer to attach metadata to non-synthetic classes, because it won't be serialized otherwise;
227241
// if not possible, though, putting it right here will at least allow non-reflective uses.
228-
val metadataOwner = generateSequence(this) { it.parent }.find { !it.isSynthetic } ?: this
242+
val metadataOwner = generateSequence(this) { it.parent }.find { !it.irClass.isSynthetic } ?: this
229243
metadataOwner.localPropertyIndices[property.getter.symbol] = metadataOwner.localProperties.size
230244
metadataOwner.localProperties.add(property.symbol)
231245
}

compiler/testData/codegen/box/reflection/properties/localDelegated/inLambdaInInline.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// TARGET_BACKEND: JVM
22
// IGNORE_BACKEND: JVM
3-
// IGNORE_INLINER: IR
43
// WITH_REFLECT
54
// FILE: 1.kt
65
package test

compiler/testData/codegen/box/reflection/properties/localDelegated/inlineFun.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// TARGET_BACKEND: JVM
2-
// IGNORE_INLINER: IR
32
// WITH_REFLECT
43

54
import kotlin.reflect.*

0 commit comments

Comments
 (0)