From 2ff011af17532fa70e7582567a54e7926ee81a6d Mon Sep 17 00:00:00 2001 From: pyos Date: Fri, 9 Oct 2020 10:27:28 +0200 Subject: [PATCH] JVM_IR: add an assertion and a comment about property references I once again forgot why we don't cache property reference classes and had to refer to the internal chat. --- .../kotlin/backend/jvm/lower/PropertyReferenceLowering.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt index 76ece73dc19..000108733d4 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt @@ -216,7 +216,7 @@ private class PropertyReferenceLowering(val context: JvmBackendContext) : IrElem currentClassData = data.parent // Put the new field at the beginning so that static delegated properties with initializers work correctly. - // Since we do not cache property references, the new field does not reference anything else. + // Since we do not cache property references with bound receivers, the new field does not reference anything else. if (data.kProperties.isNotEmpty()) { declaration.declarations.add(0, data.kPropertiesField.apply { parent = declaration @@ -266,6 +266,9 @@ private class PropertyReferenceLowering(val context: JvmBackendContext) : IrElem // does not support local variables or bound receivers (e.g. `Class()::field`) and is slower, but takes up less space. // Example: `C::property` -> `Reflection.property1(PropertyReference1Impl(C::class, "property", "getProperty()LType;"))`. private fun createReflectedKProperty(expression: IrCallableReference<*>): IrExpression { + assert(expression.dispatchReceiver == null && expression.extensionReceiver == null) { + "cannot create a reflected KProperty if the reference has a bound receiver: ${expression.render()}" + } val referenceKind = propertyReferenceKindFor(expression) return context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol, expression.startOffset, expression.endOffset).run { irCall(referenceKind.wrapper).apply { @@ -291,6 +294,8 @@ private class PropertyReferenceLowering(val context: JvmBackendContext) : IrElem // and then `C()::property` -> `C$property$0(C())`. // private fun createSpecializedKProperty(expression: IrCallableReference<*>): IrExpression { + // We do not reuse classes for non-reflective property references because they would not have + // a valid enclosing method if the same property is referenced at many points. val referenceClass = createKPropertySubclass(expression) return context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol, expression.startOffset, expression.endOffset).irBlock { +referenceClass