@@ -94,10 +94,12 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : IrEle
94
94
private val useOptimizedSuperClass =
95
95
context.state.generateOptimizedCallableReferenceSuperClasses
96
96
97
+ private val IrClass .isSynthetic
98
+ get() = metadata !is MetadataSource .File && metadata !is MetadataSource .Class && metadata !is MetadataSource .Script
99
+
97
100
private val IrMemberAccessExpression <* >.propertyContainer: IrDeclarationParent
98
101
get() = if (this is IrLocalDelegatedPropertyReference )
99
- currentClassData?.localPropertyOwner(getter)
100
- ? : throw AssertionError (" local property reference before declaration: ${render()} " )
102
+ findClassOwner()
101
103
else
102
104
getter?.owner?.parent ? : field?.owner?.parent ? : error(" Property without getter or field: ${dump()} " )
103
105
@@ -106,6 +108,23 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : IrEle
106
108
private val IrField .fakeGetterSignature: String
107
109
get() = " ${JvmAbi .getterName(name.asString())} ()${context.defaultMethodSignatureMapper.mapReturnType(this )} "
108
110
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
+
109
128
private fun IrBuilderWithScope.computeSignatureString (expression : IrMemberAccessExpression <* >): IrExpression {
110
129
if (expression is IrLocalDelegatedPropertyReference ) {
111
130
// 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
213
232
214
233
val localProperties = mutableListOf<IrLocalDelegatedPropertySymbol >()
215
234
val localPropertyIndices = mutableMapOf<IrSymbol , Int >()
216
- val isSynthetic = irClass.metadata !is MetadataSource .File && irClass.metadata !is MetadataSource .Class &&
217
- irClass.metadata !is MetadataSource .Script
218
235
219
236
fun localPropertyIndex (getter : IrSymbol ): Int? =
220
237
localPropertyIndices[getter] ? : parent?.localPropertyIndex(getter)
221
238
222
- fun localPropertyOwner (getter : IrSymbol ): IrClass ? =
223
- if (getter in localPropertyIndices) irClass else parent?.localPropertyOwner(getter)
224
-
225
239
fun rememberLocalProperty (property : IrLocalDelegatedProperty ) {
226
240
// Prefer to attach metadata to non-synthetic classes, because it won't be serialized otherwise;
227
241
// 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
229
243
metadataOwner.localPropertyIndices[property.getter.symbol] = metadataOwner.localProperties.size
230
244
metadataOwner.localProperties.add(property.symbol)
231
245
}
0 commit comments