[K/N] Fix work with adapted function references

Their parsing was totally incorrect for K2, and sometimes incorrect for
K1. After this commit it uses same code as for JVM.

^KT-55462
This commit is contained in:
Pavel Kunyavskiy
2023-01-24 12:42:19 +01:00
committed by Space Team
parent 9a693fa967
commit cb655d2d37
25 changed files with 292 additions and 32 deletions
@@ -155,12 +155,17 @@ internal class FunctionReferenceLowering(val generationState: NativeGenerationSt
break
}
if (!expression.type.isFunction() && !expression.type.isKFunction()
&& !expression.type.isKSuspendFunction()) {
if (!expression.type.isFunction() && !expression.type.isKFunction() &&
!expression.type.isKSuspendFunction() && !expression.type.isSuspendFunction()) {
// Not a subject of this lowering.
return expression
}
if (expression.origin.isLambda && expression.type.isSuspendFunction()) {
// Handled later by coroutines lowerings
return expression
}
return transformFunctionReference(expression)
}
@@ -203,12 +208,10 @@ internal class FunctionReferenceLowering(val generationState: NativeGenerationSt
private val unboundFunctionParameters = functionParameters - boundFunctionParameters
private val isLambda = functionReference.origin.isLambda
private val isKFunction = functionReference.type.isKFunction()
private val isKSuspendFunction = functionReference.type.isKSuspendFunction()
private val adaptedReferenceOriginalTarget: IrFunction? = functionReference.reflectionTarget?.owner
private val functionReferenceTarget = adaptedReferenceOriginalTarget ?: referencedFunction
private val isK = functionReference.type.isKFunction() || functionReference.type.isKSuspendFunction()
private val isSuspend = functionReference.type.isSuspendFunction() || functionReference.type.isKSuspendFunction()
private val adaptedReferenceOriginalTarget = referencedFunction.getAdapteeFromAdaptedForReferenceFunction()
private val functionReferenceTarget = adaptedReferenceOriginalTarget ?:referencedFunction
/**
* The first element of a pair is a type parameter of [referencedFunction], the second element is its argument in
@@ -329,8 +332,8 @@ internal class FunctionReferenceLowering(val generationState: NativeGenerationSt
)
}
val superClass = when {
isKSuspendFunction -> kSuspendFunctionImplSymbol.typeWith(functionReturnType)
isLambda -> irBuiltIns.anyType
isSuspend -> kSuspendFunctionImplSymbol.typeWith(functionReturnType)
else -> kFunctionImplSymbol.typeWith(functionReturnType)
}
val superTypes = mutableListOf(superClass)
@@ -342,12 +345,12 @@ internal class FunctionReferenceLowering(val generationState: NativeGenerationSt
transformedSuperMethod = remappedSuperType.classOrNull!!.functions.single { it.owner.modality == Modality.ABSTRACT }.owner
} else {
val numberOfParameters = unboundFunctionParameters.size
if (isKSuspendFunction) {
val suspendFunctionClass = symbols.kSuspendFunctionN(numberOfParameters).owner
if (isSuspend) {
val suspendFunctionClass = (if (isK) symbols.kSuspendFunctionN(numberOfParameters) else symbols.suspendFunctionN(numberOfParameters)).owner
superTypes += suspendFunctionClass.typeWith(functionParameterAndReturnTypes)
transformedSuperMethod = suspendFunctionClass.invokeFun!!
} else {
val functionClass = (if (isKFunction) symbols.kFunctionN(numberOfParameters) else symbols.functionN(numberOfParameters)).owner
val functionClass = (if (isK) symbols.kFunctionN(numberOfParameters) else symbols.functionN(numberOfParameters)).owner
superTypes += functionClass.typeWith(functionParameterAndReturnTypes)
transformedSuperMethod = functionClass.invokeFun!!
}
@@ -437,7 +440,7 @@ internal class FunctionReferenceLowering(val generationState: NativeGenerationSt
body = context.createIrBuilder(symbol, startOffset, endOffset).irBlockBody {
val superConstructor = when {
isKSuspendFunction -> kSuspendFunctionImplConstructorSymbol.owner
this@FunctionReferenceBuilder.isSuspend -> kSuspendFunctionImplConstructorSymbol.owner
isLambda -> irBuiltIns.anyClass.owner.constructors.single()
else -> kFunctionImplConstructorSymbol.owner
}
@@ -472,7 +475,7 @@ internal class FunctionReferenceLowering(val generationState: NativeGenerationSt
listOfNotNull(
(1 shl 0).takeIf { referencedFunction.isSuspend },
(1 shl 1).takeIf { hasVarargMappedToElement() },
(1 shl 2).takeIf { adaptedReferenceOriginalTarget?.isSuspend == false && referencedFunction.isSuspend },
(1 shl 2).takeIf { isSuspendConversion() },
(1 shl 3).takeIf { isCoercedToUnit() },
(1 shl 4).takeIf { isFunInterfaceConstructorAdapter() }
).sum()
@@ -489,6 +492,9 @@ internal class FunctionReferenceLowering(val generationState: NativeGenerationSt
private fun isCoercedToUnit() =
adaptedReferenceOriginalTarget?.returnType?.isUnit() == false && referencedFunction.returnType.isUnit()
private fun isSuspendConversion() =
adaptedReferenceOriginalTarget?.isSuspend == false && referencedFunction.isSuspend
private fun hasVarargMappedToElement(): Boolean {
if (adaptedReferenceOriginalTarget == null) return false
val originalParameters = adaptedReferenceOriginalTarget.allParameters