JVM IR: remove obsolete hack in JvmMultifileClass facade generation

This commit is contained in:
Alexander Udalov
2019-11-05 18:41:28 +01:00
parent 5d8aac456f
commit 7a2c467bb5
4 changed files with 17 additions and 46 deletions
@@ -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 <reified T : IrElement> T.deepCopyWithWrappedDescriptors(initialParent: IrDeclarationParent? = null): T =
deepCopyWithSymbols(initialParent, DescriptorsToIrRemapper).also {
it.acceptVoid(WrappedDescriptorPatcher)
}
object DescriptorsToIrRemapper : DescriptorsRemapper {
override fun remapDeclaredClass(descriptor: ClassDescriptor) =
@@ -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<IrFieldSymbol, IrFieldSymbol>
) : FileLoweringPass, IrElementTransformerVoid() {
@@ -214,13 +194,21 @@ private class UpdateFieldCallSites(
private class UpdateFunctionCallSites(
private val functionDelegates: MutableMap<IrFunctionSymbol, IrFunctionSymbol>
) : FileLoweringPass, IrElementTransformerVoid() {
) : FileLoweringPass, IrElementTransformer<IrFunction?> {
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 {
@@ -33,11 +33,8 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import java.util.*
inline fun <reified T : IrElement> T.deepCopyWithSymbols(
initialParent: IrDeclarationParent? = null,
descriptorRemapper: DescriptorsRemapper = DescriptorsRemapper.Default
): T {
val symbolRemapper = DeepCopySymbolRemapper(descriptorRemapper)
inline fun <reified T : IrElement> 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
@@ -1,6 +1,4 @@
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// WITH_RUNTIME
@file:JvmName("Test")