[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:
committed by
Space Team
parent
9a693fa967
commit
cb655d2d37
+20
-14
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user