diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt index 26a09f2a755..5bc78df535c 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol +import org.jetbrains.kotlin.ir.symbols.IrLocalDelegatedPropertySymbol import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable import org.jetbrains.kotlin.ir.util.SymbolTable @@ -60,6 +61,8 @@ class JvmBackendContext( localClassInfo[container.attributeOwnerId] = value } + internal val localDelegatedProperties = mutableMapOf>() + override var inVerbosePhase: Boolean = false override val configuration get() = state.configuration diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt index a8bdff29586..64d18895753 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.lower.constantValue import org.jetbrains.kotlin.codegen.* +import org.jetbrains.kotlin.codegen.binding.CodegenBinding import org.jetbrains.kotlin.codegen.inline.DefaultSourceMapper import org.jetbrains.kotlin.codegen.inline.SourceMapper import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings @@ -124,6 +125,14 @@ open class ClassCodegen protected constructor( } private fun generateKotlinMetadataAnnotation() { + val localDelegatedProperties = (irClass.attributeOwnerId as? IrClass)?.let(context.localDelegatedProperties::get) + if (localDelegatedProperties != null && localDelegatedProperties.isNotEmpty()) { + // Remove this check once CodegenAnnotatingVisitor is no longer used in JVM IR + if (state.bindingContext.get(CodegenBinding.DELEGATED_PROPERTIES, type).isNullOrEmpty()) { + state.bindingTrace.record(CodegenBinding.DELEGATED_PROPERTIES, type, localDelegatedProperties.map { it.descriptor }) + } + } + when (val metadata = irClass.metadata) { is MetadataSource.Class -> { val classProto = serializer!!.classProto(metadata.descriptor).build() diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt index 2e790c280f9..2f88a687f30 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.ir.expressions.IrFunctionReference import org.jetbrains.kotlin.ir.expressions.IrReturn import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol +import org.jetbrains.kotlin.ir.symbols.IrLocalDelegatedPropertySymbol import org.jetbrains.kotlin.ir.util.copyTypeAndValueArgumentsFrom import org.jetbrains.kotlin.ir.util.irCall import org.jetbrains.kotlin.ir.util.isInterface @@ -74,6 +75,13 @@ private class InterfaceLowering(val context: JvmBackendContext) : IrElementTrans irClass.declarations.removeAll { it is IrFunction && removedFunctions.containsKey(it.symbol) } + + // Move metadata for local delegated properties from the interface to DefaultImpls, since this is where kotlin-reflect looks for it. + val localDelegatedProperties = context.localDelegatedProperties[irClass.attributeOwnerId as IrClass] + if (localDelegatedProperties != null) { + context.localDelegatedProperties[defaultImplsIrClass.attributeOwnerId as IrClass] = localDelegatedProperties + context.localDelegatedProperties[irClass.attributeOwnerId as IrClass] = emptyList() + } } private fun shouldRemoveFunction(function: IrFunction): Boolean = 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 5d76998e916..b7c03494644 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 @@ -22,10 +22,7 @@ import org.jetbrains.kotlin.ir.builders.declarations.buildField import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl -import org.jetbrains.kotlin.ir.symbols.IrClassSymbol -import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol -import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol -import org.jetbrains.kotlin.ir.symbols.IrSymbol +import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.types.createType import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection @@ -331,6 +328,9 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class }) } }) + + context.localDelegatedProperties[irClass.attributeOwnerId as IrClass] = + kProperties.mapNotNull { it.key.symbol as? IrLocalDelegatedPropertySymbol } } irClass.declarations.addAll(0, kPropertyClasses.values) }