Fix building fake overrides for sam and function references
This commit is contained in:
committed by
Space Team
parent
95eaf3d234
commit
ea3713f051
+8
-2
@@ -219,7 +219,7 @@ abstract class SingleAbstractMethodLowering(val context: CommonBackendContext) :
|
||||
isSuspend = originalSuperMethod.isSuspend
|
||||
setSourceRange(createFor)
|
||||
}.apply {
|
||||
overriddenSymbols = listOf(transformedSuperMethod.symbol)
|
||||
overriddenSymbols = listOf(originalSuperMethod.symbol)
|
||||
dispatchReceiverParameter = subclass.thisReceiver!!.copyTo(this)
|
||||
extensionReceiverParameter = originalSuperMethod.extensionReceiverParameter?.copyTo(this)
|
||||
valueParameters = originalSuperMethod.valueParameters.map { it.copyTo(this) }
|
||||
@@ -239,7 +239,13 @@ abstract class SingleAbstractMethodLowering(val context: CommonBackendContext) :
|
||||
if (superType.needEqualsHashCodeMethods)
|
||||
generateEqualsHashCode(subclass, superType, field)
|
||||
|
||||
subclass.addFakeOverrides(context.typeSystem)
|
||||
subclass.addFakeOverrides(
|
||||
context.typeSystem,
|
||||
// Built function overrides originalSuperMethod, while, if parent class is already lowered, it would
|
||||
// transformedSuperMethod in its declaration list. We need not fake override in that case.
|
||||
// Later lowerings will fix it and replace function with one overriding transformedSuperMethod.
|
||||
ignoredParentSymbols = listOf(transformedSuperMethod.symbol)
|
||||
)
|
||||
|
||||
return subclass
|
||||
}
|
||||
|
||||
@@ -171,7 +171,8 @@ class IrOverridingUtil(
|
||||
fun buildFakeOverridesForClassUsingOverriddenSymbols(
|
||||
clazz: IrClass,
|
||||
implementedMembers: List<IrOverridableMember> = emptyList(),
|
||||
compatibilityMode: Boolean
|
||||
compatibilityMode: Boolean,
|
||||
ignoredParentSymbols: List<IrSymbol> = emptyList()
|
||||
): List<IrOverridableMember> {
|
||||
val overriddenMembers = (clazz.declarations.filterIsInstance<IrOverridableMember>() + implementedMembers)
|
||||
.flatMap { member -> member.overriddenSymbols.map { it.owner } }
|
||||
@@ -182,7 +183,7 @@ class IrOverridingUtil(
|
||||
superClass.declarations
|
||||
.filterIsInstance<IrOverridableMember>()
|
||||
.filterNot {
|
||||
it in overriddenMembers || it.isStaticMember || DescriptorVisibilities.isPrivate(it.visibility)
|
||||
it in overriddenMembers || it.symbol in ignoredParentSymbols || it.isStaticMember || DescriptorVisibilities.isPrivate(it.visibility)
|
||||
}
|
||||
.map { overriddenMember ->
|
||||
val fakeOverride = fakeOverrideBuilder.fakeOverrideMember(superType, overriddenMember, clazz)
|
||||
|
||||
@@ -1125,9 +1125,16 @@ private class FakeOverrideBuilderForLowerings : FakeOverrideBuilderStrategy(empt
|
||||
}
|
||||
}
|
||||
|
||||
fun IrClass.addFakeOverrides(typeSystem: IrTypeSystemContext, implementedMembers: List<IrOverridableMember> = emptyList()) {
|
||||
fun IrClass.addFakeOverrides(
|
||||
typeSystem: IrTypeSystemContext,
|
||||
implementedMembers: List<IrOverridableMember> = emptyList(),
|
||||
ignoredParentSymbols: List<IrSymbol> = emptyList()
|
||||
) {
|
||||
IrOverridingUtil(typeSystem, FakeOverrideBuilderForLowerings())
|
||||
.buildFakeOverridesForClassUsingOverriddenSymbols(this, implementedMembers, compatibilityMode = false)
|
||||
.buildFakeOverridesForClassUsingOverriddenSymbols(this,
|
||||
implementedMembers = implementedMembers,
|
||||
compatibilityMode = false,
|
||||
ignoredParentSymbols = ignoredParentSymbols)
|
||||
.forEach { addChild(it) }
|
||||
}
|
||||
|
||||
|
||||
+11
-2
@@ -11,11 +11,20 @@ import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
import helpers.EmptyContinuation
|
||||
|
||||
suspend fun run(block: suspend () -> Unit) = A(block).run()
|
||||
suspend fun runA(block: suspend () -> Unit) = A(block).run()
|
||||
suspend fun runC(block: suspend () -> Unit) = C(block).run()
|
||||
|
||||
fun box(): String {
|
||||
suspend {
|
||||
run {}
|
||||
runA {}
|
||||
runC {}
|
||||
A { }.run()
|
||||
C { }.run()
|
||||
}.startCoroutine(EmptyContinuation)
|
||||
return "OK"
|
||||
}
|
||||
|
||||
// FILE: c.kt
|
||||
fun interface C {
|
||||
suspend fun run()
|
||||
}
|
||||
|
||||
+17
-23
@@ -26,7 +26,6 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
@@ -194,8 +193,6 @@ internal class FunctionReferenceLowering(val context: Context) : FileLoweringPas
|
||||
private val isKFunction = functionReference.type.isKFunction()
|
||||
private val isKSuspendFunction = functionReference.type.isKSuspendFunction()
|
||||
|
||||
private val samSuperClass = samSuperType?.let { it.classOrNull ?: error("Expected a class but was: ${it.render()}") }
|
||||
|
||||
private val adaptedReferenceOriginalTarget: IrFunction? = functionReference.reflectionTarget?.owner
|
||||
|
||||
private val functionReferenceTarget = adaptedReferenceOriginalTarget ?: referencedFunction
|
||||
@@ -251,31 +248,25 @@ internal class FunctionReferenceLowering(val context: Context) : FileLoweringPas
|
||||
else -> kFunctionImplSymbol.typeWith(functionReturnType)
|
||||
}
|
||||
val superTypes = mutableListOf(superClass)
|
||||
val transformedSuperMethod: IrSimpleFunction
|
||||
if (samSuperType != null) {
|
||||
superTypes += samSuperType
|
||||
|
||||
val sam = samSuperClass!!.functions.single { it.owner.modality == Modality.ABSTRACT }
|
||||
buildInvokeMethod(sam.owner)
|
||||
val samSuperClass = samSuperType.classOrNull ?: error("Expected a class but was: ${samSuperType.render()}")
|
||||
transformedSuperMethod = samSuperClass.functions.single { it.owner.modality == Modality.ABSTRACT }.owner
|
||||
} else {
|
||||
val numberOfParameters = unboundFunctionParameters.size
|
||||
val functionClass: IrClass?
|
||||
val suspendFunctionClass: IrClass?
|
||||
if (isKSuspendFunction) {
|
||||
functionClass = null
|
||||
suspendFunctionClass = symbols.kSuspendFunctionN(numberOfParameters).owner
|
||||
val suspendFunctionClass = symbols.kSuspendFunctionN(numberOfParameters).owner
|
||||
superTypes += suspendFunctionClass.typeWith(functionParameterAndReturnTypes)
|
||||
transformedSuperMethod = suspendFunctionClass.getInvokeFunction()
|
||||
} else {
|
||||
functionClass = (if (isKFunction) symbols.kFunctionN(numberOfParameters) else symbols.functionN(numberOfParameters)).owner
|
||||
suspendFunctionClass = null
|
||||
val functionClass = (if (isKFunction) symbols.kFunctionN(numberOfParameters) else symbols.functionN(numberOfParameters)).owner
|
||||
superTypes += functionClass.typeWith(functionParameterAndReturnTypes)
|
||||
}
|
||||
|
||||
if (functionClass != null)
|
||||
buildInvokeMethod(functionClass.getInvokeFunction())
|
||||
if (suspendFunctionClass != null) {
|
||||
buildInvokeMethod(suspendFunctionClass.getInvokeFunction())
|
||||
transformedSuperMethod = functionClass.getInvokeFunction()
|
||||
}
|
||||
}
|
||||
val originalSuperMethod = context.mapping.functionWithContinuationsToSuspendFunctions[transformedSuperMethod] ?: transformedSuperMethod
|
||||
buildInvokeMethod(originalSuperMethod)
|
||||
|
||||
functionReferenceClass.superTypes += superTypes
|
||||
if (!isLambda) {
|
||||
@@ -329,7 +320,13 @@ internal class FunctionReferenceLowering(val context: Context) : FileLoweringPas
|
||||
}
|
||||
}
|
||||
|
||||
functionReferenceClass.addFakeOverrides(context.typeSystem)
|
||||
functionReferenceClass.addFakeOverrides(
|
||||
context.typeSystem,
|
||||
// Built function overrides originalSuperMethod, while, if parent class is already lowered, it would
|
||||
// transformedSuperMethod in its declaration list. We need not fake override in that case.
|
||||
// Later lowerings will fix it and replace function with one overriding transformedSuperMethod.
|
||||
ignoredParentSymbols = listOf(transformedSuperMethod.symbol)
|
||||
)
|
||||
|
||||
return functionReferenceClass
|
||||
}
|
||||
@@ -428,10 +425,7 @@ internal class FunctionReferenceLowering(val context: Context) : FileLoweringPas
|
||||
return false
|
||||
}
|
||||
|
||||
private fun buildInvokeMethod(superFunction: IrSimpleFunction) =
|
||||
buildInvokeMethodImpl(context.mapping.functionWithContinuationsToSuspendFunctions[superFunction] ?: superFunction)
|
||||
|
||||
private fun buildInvokeMethodImpl(superFunction: IrSimpleFunction): IrSimpleFunction {
|
||||
private fun buildInvokeMethod(superFunction: IrSimpleFunction): IrSimpleFunction {
|
||||
return IrFunctionImpl(
|
||||
startOffset, endOffset,
|
||||
DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL,
|
||||
|
||||
Reference in New Issue
Block a user