diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/DeepCopyWithWrappedDescriptors.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/DescriptorsToIrRemapper.kt similarity index 89% rename from compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/DeepCopyWithWrappedDescriptors.kt rename to compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/DescriptorsToIrRemapper.kt index 5b61198af95..0936005152e 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/DeepCopyWithWrappedDescriptors.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/DescriptorsToIrRemapper.kt @@ -10,21 +10,9 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.util.DescriptorsRemapper -import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols import org.jetbrains.kotlin.ir.util.parentAsClass import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid -import org.jetbrains.kotlin.ir.visitors.acceptVoid - -/* - TODO: Does not preserve getter/setter descriptors as implementations of PropertyAccessorDescriptor. - This causes problems for KotlinTypeMapper.mapFunctionName (maybe other places as well) - */ - -inline fun T.deepCopyWithWrappedDescriptors(initialParent: IrDeclarationParent? = null): T = - deepCopyWithSymbols(initialParent, DescriptorsToIrRemapper).also { - it.acceptVoid(WrappedDescriptorPatcher) - } object DescriptorsToIrRemapper : DescriptorsRemapper { override fun remapDeclaredClass(descriptor: ClassDescriptor) = diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/GenerateMultifileFacades.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/GenerateMultifileFacades.kt index d9324d1ca61..f28651ae5e2 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/GenerateMultifileFacades.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/GenerateMultifileFacades.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.backend.jvm.lower import org.jetbrains.kotlin.backend.common.FileLoweringPass -import org.jetbrains.kotlin.backend.common.deepCopyWithWrappedDescriptors import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor import org.jetbrains.kotlin.backend.common.ir.passTypeArgumentsFrom import org.jetbrains.kotlin.backend.common.lower @@ -22,9 +21,7 @@ import org.jetbrains.kotlin.backend.jvm.codegen.fileParent import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor -import org.jetbrains.kotlin.ir.SourceManager -import org.jetbrains.kotlin.ir.SourceRangeInfo -import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET +import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.builders.declarations.buildClass import org.jetbrains.kotlin.ir.builders.irBlockBody import org.jetbrains.kotlin.ir.builders.irCall @@ -42,8 +39,8 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols -import org.jetbrains.kotlin.ir.util.dump import org.jetbrains.kotlin.ir.util.transformFlat +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.resolve.jvm.JvmClassName @@ -163,8 +160,7 @@ private fun IrFunction.createMultifileDelegateIfNeeded(context: JvmBackendContex // TODO: perform copy of the signature only, without body val function = deepCopyWithSymbols(facadeClass) function.body = context.createIrBuilder(symbol).irBlockBody { - val functionForCall = computeFunctionForCall() - +irReturn(irCall(functionForCall).also { call -> + +irReturn(irCall(this@createMultifileDelegateIfNeeded).also { call -> call.passTypeArgumentsFrom(function) function.extensionReceiverParameter?.let { parameter -> call.extensionReceiver = irGet(parameter) @@ -181,22 +177,6 @@ private fun IrFunction.createMultifileDelegateIfNeeded(context: JvmBackendContex return function } -// This deep copy is needed while we still use KotlinTypeMapper to map signatures in method calls. Without it, KotlinTypeMapper takes -// the descriptor and assumes that a call to that function must go through the public facade (see mapOwner call in mapToCallableMethod), -// which results in endless recursion here. With this copy, we trick it into thinking that the function is actually a static function -// in a class whose name is the name of the multi-file part, as opposed to being top level. -private fun IrFunction.computeFunctionForCall(): IrFunction { - val property = (this as? IrSimpleFunction)?.correspondingPropertySymbol?.owner - ?: return deepCopyWithWrappedDescriptors(parent) - - val propertyCopy = property.deepCopyWithWrappedDescriptors(property.parent) - return when (this) { - property.getter -> propertyCopy.getter!! - property.setter -> propertyCopy.setter!! - else -> error("Property accessor must be getter or setter: ${dump()}") - } -} - private class UpdateFieldCallSites( private val movedFields: Map ) : FileLoweringPass, IrElementTransformerVoid() { @@ -214,13 +194,21 @@ private class UpdateFieldCallSites( private class UpdateFunctionCallSites( private val functionDelegates: MutableMap -) : FileLoweringPass, IrElementTransformerVoid() { +) : FileLoweringPass, IrElementTransformer { override fun lower(irFile: IrFile) { - irFile.transformChildrenVoid(this) + irFile.transformChildren(this, null) } - override fun visitCall(expression: IrCall): IrExpression { - val newFunction = functionDelegates[expression.symbol] ?: return super.visitCall(expression) + override fun visitFunction(declaration: IrFunction, data: IrFunction?): IrStatement = + super.visitFunction(declaration, declaration) + + override fun visitCall(expression: IrCall, data: IrFunction?): IrElement { + if (data?.origin == JvmLoweredDeclarationOrigin.MULTIFILE_BRIDGE) + return super.visitCall(expression, data) + + val newFunction = functionDelegates[expression.symbol] + ?: return super.visitCall(expression, data) + return expression.run { // TODO: deduplicate this with ReplaceKFunctionInvokeWithFunctionInvoke IrCallImpl(startOffset, endOffset, type, newFunction).apply { diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTreeWithSymbols.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTreeWithSymbols.kt index 2d60e6d091f..4fad13596f8 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTreeWithSymbols.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTreeWithSymbols.kt @@ -33,11 +33,8 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import java.util.* -inline fun T.deepCopyWithSymbols( - initialParent: IrDeclarationParent? = null, - descriptorRemapper: DescriptorsRemapper = DescriptorsRemapper.Default -): T { - val symbolRemapper = DeepCopySymbolRemapper(descriptorRemapper) +inline fun T.deepCopyWithSymbols(initialParent: IrDeclarationParent? = null): T { + val symbolRemapper = DeepCopySymbolRemapper() acceptVoid(symbolRemapper) val typeRemapper = DeepCopyTypeRemapper(symbolRemapper) return transform(DeepCopyIrTreeWithSymbols(symbolRemapper, typeRemapper), null).patchDeclarationParents(initialParent) as T diff --git a/compiler/testData/codegen/box/jvmName/multifileClassWithLocalGeneric.kt b/compiler/testData/codegen/box/jvmName/multifileClassWithLocalGeneric.kt index 805d38f74a6..334fd082b2a 100644 --- a/compiler/testData/codegen/box/jvmName/multifileClassWithLocalGeneric.kt +++ b/compiler/testData/codegen/box/jvmName/multifileClassWithLocalGeneric.kt @@ -1,6 +1,4 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM - // WITH_RUNTIME @file:JvmName("Test")