JVM IR: remove obsolete hack in JvmMultifileClass facade generation
This commit is contained in:
-12
@@ -10,21 +10,9 @@ import org.jetbrains.kotlin.descriptors.*
|
|||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.util.DescriptorsRemapper
|
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.util.parentAsClass
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
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 <reified T : IrElement> T.deepCopyWithWrappedDescriptors(initialParent: IrDeclarationParent? = null): T =
|
|
||||||
deepCopyWithSymbols(initialParent, DescriptorsToIrRemapper).also {
|
|
||||||
it.acceptVoid(WrappedDescriptorPatcher)
|
|
||||||
}
|
|
||||||
|
|
||||||
object DescriptorsToIrRemapper : DescriptorsRemapper {
|
object DescriptorsToIrRemapper : DescriptorsRemapper {
|
||||||
override fun remapDeclaredClass(descriptor: ClassDescriptor) =
|
override fun remapDeclaredClass(descriptor: ClassDescriptor) =
|
||||||
+15
-27
@@ -6,7 +6,6 @@
|
|||||||
package org.jetbrains.kotlin.backend.jvm.lower
|
package org.jetbrains.kotlin.backend.jvm.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
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.createImplicitParameterDeclarationWithWrappedDescriptor
|
||||||
import org.jetbrains.kotlin.backend.common.ir.passTypeArgumentsFrom
|
import org.jetbrains.kotlin.backend.common.ir.passTypeArgumentsFrom
|
||||||
import org.jetbrains.kotlin.backend.common.lower
|
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.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor
|
||||||
import org.jetbrains.kotlin.ir.SourceManager
|
import org.jetbrains.kotlin.ir.*
|
||||||
import org.jetbrains.kotlin.ir.SourceRangeInfo
|
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
|
||||||
import org.jetbrains.kotlin.ir.builders.declarations.buildClass
|
import org.jetbrains.kotlin.ir.builders.declarations.buildClass
|
||||||
import org.jetbrains.kotlin.ir.builders.irBlockBody
|
import org.jetbrains.kotlin.ir.builders.irBlockBody
|
||||||
import org.jetbrains.kotlin.ir.builders.irCall
|
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.IrFieldSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
|
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.util.transformFlat
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
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
|
// TODO: perform copy of the signature only, without body
|
||||||
val function = deepCopyWithSymbols(facadeClass)
|
val function = deepCopyWithSymbols(facadeClass)
|
||||||
function.body = context.createIrBuilder(symbol).irBlockBody {
|
function.body = context.createIrBuilder(symbol).irBlockBody {
|
||||||
val functionForCall = computeFunctionForCall()
|
+irReturn(irCall(this@createMultifileDelegateIfNeeded).also { call ->
|
||||||
+irReturn(irCall(functionForCall).also { call ->
|
|
||||||
call.passTypeArgumentsFrom(function)
|
call.passTypeArgumentsFrom(function)
|
||||||
function.extensionReceiverParameter?.let { parameter ->
|
function.extensionReceiverParameter?.let { parameter ->
|
||||||
call.extensionReceiver = irGet(parameter)
|
call.extensionReceiver = irGet(parameter)
|
||||||
@@ -181,22 +177,6 @@ private fun IrFunction.createMultifileDelegateIfNeeded(context: JvmBackendContex
|
|||||||
return function
|
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 class UpdateFieldCallSites(
|
||||||
private val movedFields: Map<IrFieldSymbol, IrFieldSymbol>
|
private val movedFields: Map<IrFieldSymbol, IrFieldSymbol>
|
||||||
) : FileLoweringPass, IrElementTransformerVoid() {
|
) : FileLoweringPass, IrElementTransformerVoid() {
|
||||||
@@ -214,13 +194,21 @@ private class UpdateFieldCallSites(
|
|||||||
|
|
||||||
private class UpdateFunctionCallSites(
|
private class UpdateFunctionCallSites(
|
||||||
private val functionDelegates: MutableMap<IrFunctionSymbol, IrFunctionSymbol>
|
private val functionDelegates: MutableMap<IrFunctionSymbol, IrFunctionSymbol>
|
||||||
) : FileLoweringPass, IrElementTransformerVoid() {
|
) : FileLoweringPass, IrElementTransformer<IrFunction?> {
|
||||||
override fun lower(irFile: IrFile) {
|
override fun lower(irFile: IrFile) {
|
||||||
irFile.transformChildrenVoid(this)
|
irFile.transformChildren(this, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall): IrExpression {
|
override fun visitFunction(declaration: IrFunction, data: IrFunction?): IrStatement =
|
||||||
val newFunction = functionDelegates[expression.symbol] ?: return super.visitCall(expression)
|
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 {
|
return expression.run {
|
||||||
// TODO: deduplicate this with ReplaceKFunctionInvokeWithFunctionInvoke
|
// TODO: deduplicate this with ReplaceKFunctionInvokeWithFunctionInvoke
|
||||||
IrCallImpl(startOffset, endOffset, type, newFunction).apply {
|
IrCallImpl(startOffset, endOffset, type, newFunction).apply {
|
||||||
|
|||||||
@@ -33,11 +33,8 @@ import org.jetbrains.kotlin.name.FqName
|
|||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
inline fun <reified T : IrElement> T.deepCopyWithSymbols(
|
inline fun <reified T : IrElement> T.deepCopyWithSymbols(initialParent: IrDeclarationParent? = null): T {
|
||||||
initialParent: IrDeclarationParent? = null,
|
val symbolRemapper = DeepCopySymbolRemapper()
|
||||||
descriptorRemapper: DescriptorsRemapper = DescriptorsRemapper.Default
|
|
||||||
): T {
|
|
||||||
val symbolRemapper = DeepCopySymbolRemapper(descriptorRemapper)
|
|
||||||
acceptVoid(symbolRemapper)
|
acceptVoid(symbolRemapper)
|
||||||
val typeRemapper = DeepCopyTypeRemapper(symbolRemapper)
|
val typeRemapper = DeepCopyTypeRemapper(symbolRemapper)
|
||||||
return transform(DeepCopyIrTreeWithSymbols(symbolRemapper, typeRemapper), null).patchDeclarationParents(initialParent) as T
|
return transform(DeepCopyIrTreeWithSymbols(symbolRemapper, typeRemapper), null).patchDeclarationParents(initialParent) as T
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
@file:JvmName("Test")
|
@file:JvmName("Test")
|
||||||
|
|||||||
Reference in New Issue
Block a user