[K2, MPP] Introduce FunctionDefaultParametersActualizerVisitor and use it in FunctionDefaultParametersActualizer

^KT-57263 Fixed
This commit is contained in:
Ivan Kochurkin
2023-03-31 22:56:31 +02:00
committed by Space Team
parent 1073797ed3
commit b7bb9c317f
22 changed files with 167 additions and 50 deletions
@@ -5,13 +5,24 @@
package org.jetbrains.kotlin.backend.common.actualizer
import org.jetbrains.kotlin.backend.common.lower.copyAndActualizeDefaultValue
import org.jetbrains.kotlin.backend.common.lower.actualize
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.declarations.copyAttributes
import org.jetbrains.kotlin.ir.expressions.IrGetValue
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.util.DeepCopyTypeRemapper
import org.jetbrains.kotlin.ir.util.SymbolRemapper
import org.jetbrains.kotlin.ir.util.TypeRemapper
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
internal class FunctionDefaultParametersActualizer(
symbolRemapper: ActualizerSymbolRemapper,
typeRemapper: DeepCopyTypeRemapper,
private val expectActualMap: Map<IrSymbol, IrSymbol>
) {
private val visitor = FunctionDefaultParametersActualizerVisitor(symbolRemapper, typeRemapper)
internal class FunctionDefaultParametersActualizer(private val expectActualMap: Map<IrSymbol, IrSymbol>) {
fun actualize() {
for ((expect, actual) in expectActualMap) {
if (expect is IrFunctionSymbol) {
@@ -24,13 +35,20 @@ internal class FunctionDefaultParametersActualizer(private val expectActualMap:
expectFunction.valueParameters.zip(actualFunction.valueParameters).forEach { (expectParameter, actualParameter) ->
val expectDefaultValue = expectParameter.defaultValue
if (actualParameter.defaultValue == null && expectDefaultValue != null) {
actualParameter.defaultValue = expectDefaultValue.copyAndActualizeDefaultValue(
actualFunction,
mapOf(),
classActualizer = { (expectActualMap[it.symbol] as IrClassSymbol).owner },
functionActualizer = { (expectActualMap[it.symbol] as IrFunctionSymbol).owner }
)
actualParameter.defaultValue = expectDefaultValue.deepCopyWithSymbols(actualFunction).transform(visitor, null)
}
}
}
}
}
private class FunctionDefaultParametersActualizerVisitor(private val symbolRemapper: SymbolRemapper, typeRemapper: TypeRemapper) :
ActualizerVisitor(symbolRemapper, typeRemapper) {
override fun visitGetValue(expression: IrGetValue): IrGetValue {
// It performs actualization of dispatch/extension receivers
// It's actual only for default parameter values of expect functions because expect functions don't have bodies
return expression.actualize(
classActualizer = { symbolRemapper.getReferencedClass(it.symbol).owner },
functionActualizer = { symbolRemapper.getReferencedFunction(it.symbol).owner }
).copyAttributes(expression)
}
}
@@ -34,7 +34,7 @@ object IrActualizer {
val symbolRemapper = ActualizerSymbolRemapper(expectActualMap)
val typeRemapper = DeepCopyTypeRemapper(symbolRemapper)
FunctionDefaultParametersActualizer(expectActualMap).actualize()
FunctionDefaultParametersActualizer(symbolRemapper, typeRemapper, expectActualMap).actualize()
MissingFakeOverridesAdder(
expectActualMap,
@@ -12,9 +12,13 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.expressions.IrGetValue
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.extractTypeParameters
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.multiplatform.OptionalAnnotationUtil
import org.jetbrains.kotlin.resolve.multiplatform.findCompatibleActualsForExpected
@@ -151,13 +155,30 @@ open class ExpectDeclarationRemover(val symbolTable: ReferenceSymbolTable, priva
defaultValue.let { originalDefault ->
declaration.defaultValue = originalDefault.copyAndActualizeDefaultValue(
function,
typeParameterSubstitutionMap.getValue(expectToActual),
classActualizer = { symbolTable.referenceClass(it.descriptor.findActualForExpect() as ClassDescriptor).owner },
functionActualizer = { symbolTable.referenceFunction(it.descriptor.findActualForExpect() as FunctionDescriptor).owner }
typeParameterSubstitutionMap.getValue(expectToActual)
)
}
}
private fun IrExpressionBody.copyAndActualizeDefaultValue(
actualFunction: IrFunction,
expectActualTypeParametersMap: Map<IrTypeParameter, IrTypeParameter>
): IrExpressionBody {
return this
.deepCopyWithSymbols(actualFunction) { symbolRemapper, _ ->
DeepCopyIrTreeWithSymbols(symbolRemapper, IrTypeParameterRemapper(expectActualTypeParametersMap))
}
.transform(object : IrElementTransformerVoid() {
override fun visitGetValue(expression: IrGetValue): IrExpression {
expression.transformChildrenVoid()
return expression.actualize(
classActualizer = { symbolTable.referenceClass(it.descriptor.findActualForExpect() as ClassDescriptor).owner },
functionActualizer = { symbolTable.referenceFunction(it.descriptor.findActualForExpect() as FunctionDescriptor).owner }
)
}
}, data = null)
}
private fun MemberDescriptor.findExpectForActual(): MemberDescriptor? {
if (!isActual) error(this)
return findCompatibleExpectsForActual().singleOrNull()
@@ -22,9 +22,6 @@ import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.util.DeepCopyIrTreeWithSymbols
import org.jetbrains.kotlin.ir.util.IrTypeParameterRemapper
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
@@ -253,28 +250,7 @@ fun ParameterDescriptor.copyAsValueParameter(newOwner: CallableDescriptor, index
else -> throw Error("Unexpected parameter descriptor: $this")
}
fun IrExpressionBody.copyAndActualizeDefaultValue(
actualFunction: IrFunction,
expectActualTypeParametersMap: Map<IrTypeParameter, IrTypeParameter>,
classActualizer: (IrClass) -> IrClass,
functionActualizer: (IrFunction) -> IrFunction
): IrExpressionBody {
return this
.deepCopyWithSymbols(actualFunction) { symbolRemapper, _ ->
DeepCopyIrTreeWithSymbols(symbolRemapper, IrTypeParameterRemapper(expectActualTypeParametersMap))
}
.transform(object : IrElementTransformerVoid() {
override fun visitGetValue(expression: IrGetValue): IrExpression {
expression.transformChildrenVoid()
return expression.actualizeForDefaultValue(
classActualizer = { classActualizer(it) },
functionActualizer = { functionActualizer(it) }
)
}
}, data = null)
}
fun IrGetValue.actualizeForDefaultValue(classActualizer: (IrClass) -> IrClass, functionActualizer: (IrFunction) -> IrFunction): IrGetValue {
fun IrGetValue.actualize(classActualizer: (IrClass) -> IrClass, functionActualizer: (IrFunction) -> IrFunction): IrGetValue {
val symbol = symbol
if (symbol !is IrValueParameterSymbol) {
return this
@@ -288,13 +264,13 @@ fun IrGetValue.actualizeForDefaultValue(classActualizer: (IrClass) -> IrClass, f
}
is IrFunction -> {
val function = functionActualizer(parent)
val actualizedFunction = functionActualizer(parent)
when (parameter) {
parent.dispatchReceiverParameter -> function.dispatchReceiverParameter!!
parent.extensionReceiverParameter -> function.extensionReceiverParameter!!
parent.dispatchReceiverParameter -> actualizedFunction.dispatchReceiverParameter!!
parent.extensionReceiverParameter -> actualizedFunction.extensionReceiverParameter!!
else -> {
assert(parent.valueParameters[parameter.index] == parameter)
function.valueParameters[parameter.index]
actualizedFunction.valueParameters[parameter.index]
}
}
}