diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/SignatureString.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/SignatureString.kt index 42c1f046e59..17362012239 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/SignatureString.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/SignatureString.kt @@ -8,9 +8,10 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics import org.jetbrains.kotlin.backend.jvm.codegen.BlockInfo import org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen import org.jetbrains.kotlin.backend.jvm.codegen.PromisedValue +import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression import org.jetbrains.kotlin.ir.expressions.IrFunctionReference -import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.ir.util.collectRealOverrides import org.jetbrains.kotlin.resolve.jvm.AsmTypes /** @@ -20,15 +21,9 @@ import org.jetbrains.kotlin.resolve.jvm.AsmTypes object SignatureString : IntrinsicMethod() { override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? { val function = (expression.getValueArgument(0) as IrFunctionReference).symbol.owner - - // TODO do not use descriptors - val declaration = codegen.context.referenceFunction( - DescriptorUtils.unwrapFakeOverride(function.descriptor).original - ).owner - - val method = codegen.context.methodSignatureMapper.mapAsmMethod(declaration) + val resolved = if (function is IrSimpleFunction) function.collectRealOverrides().first() else function + val method = codegen.context.methodSignatureMapper.mapAsmMethod(resolved) val descriptor = method.name + method.descriptor - return object : PromisedValue(codegen, AsmTypes.JAVA_STRING_TYPE, codegen.context.irBuiltIns.stringType) { override fun materialize() { codegen.mv.aconst(descriptor) 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 3f5ddff1367..5ad883758c2 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 @@ -19,10 +19,12 @@ import org.jetbrains.kotlin.backend.jvm.ir.irArrayOf import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.ir.IrStatement +import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.builders.declarations.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* +import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.types.createType import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl @@ -64,14 +66,11 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class private val IrField.signature: String get() = "${JvmAbi.getterName(name.asString())}()${context.methodSignatureMapper.mapReturnType(this)}" - private val IrMemberAccessExpression.signature: String - get() = getter?.let { getter -> - localPropertyIndices[getter]?.let { "" } - } ?: getter?.owner?.signature ?: field!!.owner.signature - private val arrayItemGetter = context.ir.symbols.array.owner.functions.single { it.name.asString() == "get" } + private val signatureStringIntrinsic = context.ir.symbols.signatureStringIntrinsic + private val kPropertyStarType = IrSimpleTypeImpl( context.irBuiltIns.kPropertyClass, false, @@ -95,6 +94,23 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class calculateOwner(expression.propertyContainer, this@PropertyReferenceLowering.context) } + private fun IrBuilderWithScope.computeSignatureString(expression: IrCallableReference): IrExpression { + return expression.getter?.let { getter -> + localPropertyIndices[getter]?.let { irString("") } + ?: if (getter.owner.origin == IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR) { + // Default property accessor. Compute the signature now, so that we will not get into trouble + // if the getter is transformed to a static method by inline classes lowering. + irString(getter.owner.signature) + } else { + // Delay the computation of the signature until after inline classes lowering to make sure + // we mangle the function names correctly for things like extension methods on inline classes. + irCall(signatureStringIntrinsic).apply { + putValueArgument(0, IrFunctionReferenceImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, expression.type, getter, 0, null)) + } + } + } ?: irString(expression.field!!.owner.signature) + } + private fun IrClass.addOverride(method: IrSimpleFunction, buildBody: IrBuilderWithScope.(List) -> IrExpression) = addFunction { setSourceRange(this@addOverride) @@ -204,7 +220,7 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class putValueArgument(0, irCall(referenceKind.reflectedSymbol.constructors.single()).apply { putValueArgument(0, buildReflectedContainerReference(expression)) putValueArgument(1, irString(expression.symbol.descriptor.name.asString())) - putValueArgument(2, irString(expression.signature)) + putValueArgument(2, computeSignatureString(expression)) }) } } @@ -266,7 +282,7 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class referenceClass.addSimpleDelegatingConstructor(superConstructor, context.irBuiltIns, isPrimary = true) referenceClass.addOverride(getName) { irString(expression.symbol.descriptor.name.asString()) } referenceClass.addOverride(getOwner) { buildReflectedContainerReference(expression) } - referenceClass.addOverride(getSignature) { irString(expression.signature) } + referenceClass.addOverride(getSignature) { computeSignatureString(expression) } val receiverField = referenceClass.addField { name = backingFieldFromSuper.name diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/inlineclasses/MemoizedInlineClassReplacements.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/inlineclasses/MemoizedInlineClassReplacements.kt index 221047a9193..c63ae8a9260 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/inlineclasses/MemoizedInlineClassReplacements.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/inlineclasses/MemoizedInlineClassReplacements.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter import org.jetbrains.kotlin.ir.builders.declarations.buildFun import org.jetbrains.kotlin.ir.builders.declarations.buildFunWithDescriptorForInlining import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionBase import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol @@ -169,8 +170,11 @@ class MemoizedInlineClassReplacements { private fun createStaticReplacement(function: IrFunction): IrReplacementFunction { val parameterMap = mutableMapOf() val replacement = buildReplacement(function) { - if (function !is IrSimpleFunction || function.overriddenSymbols.isEmpty()) + // Generate metadata for the replacement function instead of the original. + if (function is IrFunctionBase) { metadata = function.metadata + function.metadata = null + } for ((index, parameter) in function.explicitParameters.withIndex()) { val name = when (parameter) { diff --git a/compiler/testData/codegen/box/reflection/call/inlineClasses/nonOverridingVarOfInlineClass.kt b/compiler/testData/codegen/box/reflection/call/inlineClasses/nonOverridingVarOfInlineClass.kt index 33327f540d3..318deb2cebb 100644 --- a/compiler/testData/codegen/box/reflection/call/inlineClasses/nonOverridingVarOfInlineClass.kt +++ b/compiler/testData/codegen/box/reflection/call/inlineClasses/nonOverridingVarOfInlineClass.kt @@ -1,5 +1,5 @@ // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JS_IR, JS, NATIVE, JVM_IR +// IGNORE_BACKEND: JS_IR, JS, NATIVE // WITH_REFLECT import kotlin.test.assertEquals diff --git a/compiler/testData/codegen/box/reflection/call/inlineClasses/overridingFunOfInlineClass.kt b/compiler/testData/codegen/box/reflection/call/inlineClasses/overridingFunOfInlineClass.kt index 3df9e8da34d..6f6e84bf4f8 100644 --- a/compiler/testData/codegen/box/reflection/call/inlineClasses/overridingFunOfInlineClass.kt +++ b/compiler/testData/codegen/box/reflection/call/inlineClasses/overridingFunOfInlineClass.kt @@ -1,5 +1,5 @@ // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JS_IR, JS, NATIVE, JVM_IR +// IGNORE_BACKEND: JS_IR, JS, NATIVE // WITH_REFLECT import kotlin.test.assertEquals diff --git a/compiler/testData/codegen/box/reflection/call/inlineClasses/overridingVarOfInlineClass.kt b/compiler/testData/codegen/box/reflection/call/inlineClasses/overridingVarOfInlineClass.kt index 7f06afc6f08..6d98427740e 100644 --- a/compiler/testData/codegen/box/reflection/call/inlineClasses/overridingVarOfInlineClass.kt +++ b/compiler/testData/codegen/box/reflection/call/inlineClasses/overridingVarOfInlineClass.kt @@ -1,5 +1,5 @@ // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JS_IR, JS, NATIVE, JVM_IR +// IGNORE_BACKEND: JS_IR, JS, NATIVE // WITH_REFLECT import kotlin.test.assertEquals diff --git a/compiler/testData/codegen/box/reflection/call/inlineClasses/properties.kt b/compiler/testData/codegen/box/reflection/call/inlineClasses/properties.kt index 21461d764e0..6069be53e8c 100644 --- a/compiler/testData/codegen/box/reflection/call/inlineClasses/properties.kt +++ b/compiler/testData/codegen/box/reflection/call/inlineClasses/properties.kt @@ -1,5 +1,5 @@ // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JS_IR, JS, NATIVE, JVM_IR +// IGNORE_BACKEND: JS_IR, JS, NATIVE // WITH_REFLECT import kotlin.reflect.KMutableProperty2 diff --git a/compiler/testData/codegen/box/reflection/callBy/inlineClassMembers.kt b/compiler/testData/codegen/box/reflection/callBy/inlineClassMembers.kt index 383f795b97b..c8f2486f241 100644 --- a/compiler/testData/codegen/box/reflection/callBy/inlineClassMembers.kt +++ b/compiler/testData/codegen/box/reflection/callBy/inlineClassMembers.kt @@ -1,5 +1,5 @@ // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JS_IR, JS, NATIVE, JVM_IR +// IGNORE_BACKEND: JS_IR, JS, NATIVE // WITH_REFLECT import kotlin.test.assertEquals