[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
@@ -33561,6 +33561,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/dispatchReceiverValue.kt");
}
@Test
@TestMetadata("expectPropertyAsDefaultArgument.kt")
public void testExpectPropertyAsDefaultArgument() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/expectPropertyAsDefaultArgument.kt");
}
@Test
@TestMetadata("extensionReceiverValue.kt")
public void testExtensionReceiverValue() throws Exception {
@@ -33561,6 +33561,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/dispatchReceiverValue.kt");
}
@Test
@TestMetadata("expectPropertyAsDefaultArgument.kt")
public void testExpectPropertyAsDefaultArgument() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/expectPropertyAsDefaultArgument.kt");
}
@Test
@TestMetadata("extensionReceiverValue.kt")
public void testExtensionReceiverValue() throws Exception {
@@ -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]
}
}
}
@@ -1,7 +1,5 @@
// IGNORE_BACKEND: JS_IR, JS_IR_ES6, WASM
// IGNORE_BACKEND_K1: JVM, JVM_IR, JS, NATIVE
// KT-57181
// IGNORE_BACKEND_K2: NATIVE
// IGNORE_BACKEND_K1: JVM, JVM_IR, JS, JS_IR, JS_IR_ES6, NATIVE, WASM
// ISSUE: KT-57181
// WASM_MUTE_REASON: EXPECT_DEFAULT_PARAMETERS
// !LANGUAGE: +MultiPlatformProjects
// ISSUE: KT-41901
@@ -0,0 +1,18 @@
// IGNORE_BACKEND_K1: JS, JS_IR, JS_IR_ES6
// !LANGUAGE: +MultiPlatformProjects
// ISSUE: KT-57263
// MODULE: common
// TARGET_PLATFORM: Common
// FILE: common.kt
expect val traceFormatDefault: String
expect fun Trace(format: String = traceFormatDefault): String
// MODULE: platform()()(common)
// FILE: platform.kt
actual val traceFormatDefault: String = ""
actual fun Trace(format: String) = format
fun box() = Trace("OK")
@@ -1,8 +1,6 @@
// WITH_STDLIB
// IGNORE_BACKEND: JS_IR, JS_IR_ES6, WASM
// IGNORE_BACKEND_K1: JS, JVM, JVM_IR
// IGNORE_BACKEND_K1: JVM, JVM_IR, JS, JS_IR, JS_IR_ES6, NATIVE, WASM
// KT-57181
// IGNORE_BACKEND_K2: NATIVE
// JS IR & Wasm: https://youtrack.jetbrains.com/issue/KT-51225
// !LANGUAGE: +MultiPlatformProjects
// ISSUE: KT-51156
@@ -32115,6 +32115,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/dispatchReceiverValue.kt");
}
@Test
@TestMetadata("expectPropertyAsDefaultArgument.kt")
public void testExpectPropertyAsDefaultArgument() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/expectPropertyAsDefaultArgument.kt");
}
@Test
@TestMetadata("extensionReceiverValue.kt")
public void testExtensionReceiverValue() throws Exception {
@@ -33561,6 +33561,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/dispatchReceiverValue.kt");
}
@Test
@TestMetadata("expectPropertyAsDefaultArgument.kt")
public void testExpectPropertyAsDefaultArgument() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/expectPropertyAsDefaultArgument.kt");
}
@Test
@TestMetadata("extensionReceiverValue.kt")
public void testExtensionReceiverValue() throws Exception {
@@ -33561,6 +33561,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/dispatchReceiverValue.kt");
}
@Test
@TestMetadata("expectPropertyAsDefaultArgument.kt")
public void testExpectPropertyAsDefaultArgument() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/expectPropertyAsDefaultArgument.kt");
}
@Test
@TestMetadata("extensionReceiverValue.kt")
public void testExtensionReceiverValue() throws Exception {
@@ -27455,6 +27455,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
public void testAnnotations() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/annotations.kt");
}
@TestMetadata("expectPropertyAsDefaultArgument.kt")
public void testExpectPropertyAsDefaultArgument() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/expectPropertyAsDefaultArgument.kt");
}
}
}
@@ -23309,6 +23309,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/dispatchReceiverValue.kt");
}
@Test
@TestMetadata("expectPropertyAsDefaultArgument.kt")
public void testExpectPropertyAsDefaultArgument() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/expectPropertyAsDefaultArgument.kt");
}
@Test
@TestMetadata("extensionReceiverValue.kt")
public void testExtensionReceiverValue() throws Exception {
@@ -23447,6 +23447,12 @@ public class FirJsCodegenBoxTestGenerated extends AbstractFirJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/dispatchReceiverValue.kt");
}
@Test
@TestMetadata("expectPropertyAsDefaultArgument.kt")
public void testExpectPropertyAsDefaultArgument() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/expectPropertyAsDefaultArgument.kt");
}
@Test
@TestMetadata("extensionReceiverValue.kt")
public void testExtensionReceiverValue() throws Exception {
@@ -23447,6 +23447,12 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/dispatchReceiverValue.kt");
}
@Test
@TestMetadata("expectPropertyAsDefaultArgument.kt")
public void testExpectPropertyAsDefaultArgument() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/expectPropertyAsDefaultArgument.kt");
}
@Test
@TestMetadata("extensionReceiverValue.kt")
public void testExtensionReceiverValue() throws Exception {
@@ -23447,6 +23447,12 @@ public class IrJsES6CodegenBoxTestGenerated extends AbstractIrJsES6CodegenBoxTes
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/dispatchReceiverValue.kt");
}
@Test
@TestMetadata("expectPropertyAsDefaultArgument.kt")
public void testExpectPropertyAsDefaultArgument() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/expectPropertyAsDefaultArgument.kt");
}
@Test
@TestMetadata("extensionReceiverValue.kt")
public void testExtensionReceiverValue() throws Exception {
@@ -26883,6 +26883,12 @@ public class FirNativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTe
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/dispatchReceiverValue.kt");
}
@Test
@TestMetadata("expectPropertyAsDefaultArgument.kt")
public void testExpectPropertyAsDefaultArgument() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/expectPropertyAsDefaultArgument.kt");
}
@Test
@TestMetadata("extensionReceiverValue.kt")
public void testExtensionReceiverValue() throws Exception {
@@ -27495,6 +27495,12 @@ public class FirNativeCodegenBoxTestNoPLGenerated extends AbstractNativeCodegenB
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/dispatchReceiverValue.kt");
}
@Test
@TestMetadata("expectPropertyAsDefaultArgument.kt")
public void testExpectPropertyAsDefaultArgument() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/expectPropertyAsDefaultArgument.kt");
}
@Test
@TestMetadata("extensionReceiverValue.kt")
public void testExtensionReceiverValue() throws Exception {
@@ -26577,6 +26577,12 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/dispatchReceiverValue.kt");
}
@Test
@TestMetadata("expectPropertyAsDefaultArgument.kt")
public void testExpectPropertyAsDefaultArgument() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/expectPropertyAsDefaultArgument.kt");
}
@Test
@TestMetadata("extensionReceiverValue.kt")
public void testExtensionReceiverValue() throws Exception {
@@ -27189,6 +27189,12 @@ public class NativeCodegenBoxTestNoPLGenerated extends AbstractNativeCodegenBoxT
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/dispatchReceiverValue.kt");
}
@Test
@TestMetadata("expectPropertyAsDefaultArgument.kt")
public void testExpectPropertyAsDefaultArgument() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/expectPropertyAsDefaultArgument.kt");
}
@Test
@TestMetadata("extensionReceiverValue.kt")
public void testExtensionReceiverValue() throws Exception {
@@ -20879,6 +20879,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/dispatchReceiverValue.kt");
}
@TestMetadata("expectPropertyAsDefaultArgument.kt")
public void testExpectPropertyAsDefaultArgument() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/expectPropertyAsDefaultArgument.kt");
}
@TestMetadata("extensionReceiverValue.kt")
public void testExtensionReceiverValue() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/k2/defaultArguments/extensionReceiverValue.kt");