IR: minor, refactor code in ExpectDeclarationRemover
Inline unnecessary inline functions to keep stacktraces saner, fix incorrect "this" in exception message in findActualForExpect/findExpectForActual (see KT-45628).
This commit is contained in:
+33
-37
@@ -5,7 +5,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.common.lower
|
package org.jetbrains.kotlin.backend.common.lower
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.MemberDescriptor
|
import org.jetbrains.kotlin.descriptors.MemberDescriptor
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||||
@@ -23,6 +25,7 @@ import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
|||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver
|
import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.OptionalAnnotationUtil
|
import org.jetbrains.kotlin.resolve.multiplatform.OptionalAnnotationUtil
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
// `doRemove` means should expect-declaration be removed from IR
|
// `doRemove` means should expect-declaration be removed from IR
|
||||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||||
@@ -100,10 +103,11 @@ class ExpectDeclarationRemover(val symbolTable: ReferenceSymbolTable, private va
|
|||||||
// the `actual fun` or `actual constructor` for this may be in a different module.
|
// the `actual fun` or `actual constructor` for this may be in a different module.
|
||||||
// Nothing we can do with those.
|
// Nothing we can do with those.
|
||||||
// TODO they may not actually have the defaults though -- may be a frontend bug.
|
// TODO they may not actually have the defaults though -- may be a frontend bug.
|
||||||
val expectFunction = function.findExpectForActual()
|
val expectFunction =
|
||||||
val expectParameter = expectFunction?.valueParameters?.get(index) ?: return
|
function.descriptor.findExpectForActual().safeAs<FunctionDescriptor>()?.let { symbolTable.referenceFunction(it).owner }
|
||||||
|
?: return
|
||||||
|
|
||||||
val defaultValue = expectParameter.defaultValue ?: return
|
val defaultValue = expectFunction.valueParameters[index].defaultValue ?: return
|
||||||
|
|
||||||
val expectToActual = expectFunction to function
|
val expectToActual = expectFunction to function
|
||||||
if (expectToActual !in typeParameterSubstitutionMap) {
|
if (expectToActual !in typeParameterSubstitutionMap) {
|
||||||
@@ -129,30 +133,19 @@ class ExpectDeclarationRemover(val symbolTable: ReferenceSymbolTable, private va
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrFunction.findActualForExpected(): IrFunction? =
|
private fun MemberDescriptor.findActualForExpect(): MemberDescriptor? {
|
||||||
descriptor.findActualForExpect()?.let { symbolTable.referenceFunction(it).owner }
|
if (!isExpect) error(this)
|
||||||
|
return with(ExpectedActualResolver) {
|
||||||
private fun IrFunction.findExpectForActual(): IrFunction? =
|
findCompatibleActualForExpected(this@findActualForExpect.module).singleOrNull()
|
||||||
descriptor.findExpectForActual()?.let { symbolTable.referenceFunction(it).owner }
|
|
||||||
|
|
||||||
private fun IrClass.findActualForExpected(): IrClass? =
|
|
||||||
descriptor.findActualForExpect()?.let { symbolTable.referenceClass(it).owner }
|
|
||||||
|
|
||||||
private inline fun <reified T : MemberDescriptor> T.findActualForExpect() = with(ExpectedActualResolver) {
|
|
||||||
val descriptor = this@findActualForExpect
|
|
||||||
|
|
||||||
if (!descriptor.isExpect) error(this)
|
|
||||||
|
|
||||||
findCompatibleActualForExpected(descriptor.module).singleOrNull()
|
|
||||||
} as T?
|
|
||||||
|
|
||||||
private inline fun <reified T : MemberDescriptor> T.findExpectForActual() = with(ExpectedActualResolver) {
|
|
||||||
val descriptor = this@findExpectForActual
|
|
||||||
|
|
||||||
if (!descriptor.isActual) error(this) else {
|
|
||||||
findCompatibleExpectedForActual(descriptor.module).singleOrNull()
|
|
||||||
}
|
}
|
||||||
} as T?
|
}
|
||||||
|
|
||||||
|
private fun MemberDescriptor.findExpectForActual(): MemberDescriptor? {
|
||||||
|
if (!isActual) error(this)
|
||||||
|
return with(ExpectedActualResolver) {
|
||||||
|
findCompatibleExpectedForActual(this@findExpectForActual.module).singleOrNull()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun IrExpression.remapExpectValueSymbols(): IrExpression {
|
private fun IrExpression.remapExpectValueSymbols(): IrExpression {
|
||||||
return this.transform(object : IrElementTransformerVoid() {
|
return this.transform(object : IrElementTransformerVoid() {
|
||||||
@@ -179,22 +172,25 @@ class ExpectDeclarationRemover(val symbolTable: ReferenceSymbolTable, private va
|
|||||||
}
|
}
|
||||||
|
|
||||||
val parameter = symbol.owner
|
val parameter = symbol.owner
|
||||||
val parent = parameter.parent
|
|
||||||
|
|
||||||
return when (parent) {
|
return when (val parent = parameter.parent) {
|
||||||
is IrClass -> {
|
is IrClass -> {
|
||||||
assert(parameter == parent.thisReceiver)
|
assert(parameter == parent.thisReceiver)
|
||||||
parent.findActualForExpected()!!.thisReceiver!!
|
symbolTable.referenceClass(parent.descriptor.findActualForExpect() as ClassDescriptor).owner.thisReceiver!!
|
||||||
}
|
}
|
||||||
|
|
||||||
is IrFunction -> when (parameter) {
|
is IrFunction -> {
|
||||||
parent.dispatchReceiverParameter ->
|
val actualFunction =
|
||||||
parent.findActualForExpected()!!.dispatchReceiverParameter!!
|
symbolTable.referenceFunction(parent.descriptor.findActualForExpect() as FunctionDescriptor).owner
|
||||||
parent.extensionReceiverParameter ->
|
when (parameter) {
|
||||||
parent.findActualForExpected()!!.extensionReceiverParameter!!
|
parent.dispatchReceiverParameter ->
|
||||||
else -> {
|
actualFunction.dispatchReceiverParameter!!
|
||||||
assert(parent.valueParameters[parameter.index] == parameter)
|
parent.extensionReceiverParameter ->
|
||||||
parent.findActualForExpected()!!.valueParameters[parameter.index]
|
actualFunction.extensionReceiverParameter!!
|
||||||
|
else -> {
|
||||||
|
assert(parent.valueParameters[parameter.index] == parameter)
|
||||||
|
actualFunction.valueParameters[parameter.index]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user