PSI2IR: Support suspend conversion for function references
This commit is contained in:
+2
-1
@@ -689,7 +689,8 @@ class ExpressionCodegen(
|
||||
override fun visitElement(element: IrElement, data: BlockInfo) =
|
||||
throw AssertionError(
|
||||
"Unexpected IR element found during code generation. Either code generation for it " +
|
||||
"is not implemented, or it should have been lowered: ${element.render()}"
|
||||
"is not implemented, or it should have been lowered:\n" +
|
||||
element.render()
|
||||
)
|
||||
|
||||
override fun visitClass(declaration: IrClass, data: BlockInfo): PromisedValue {
|
||||
|
||||
+18
-6
@@ -77,10 +77,12 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
|
||||
|
||||
val callBuilder = unwrapCallableDescriptorAndTypeArguments(resolvedCall, context.extensions.samConversion)
|
||||
|
||||
val callableReferenceType = getTypeInferredByFrontendOrFail(ktCallableReference)
|
||||
if (resolvedCall.valueArguments.isNotEmpty() ||
|
||||
requiresCoercionToUnit(resolvedDescriptor, getTypeInferredByFrontendOrFail(ktCallableReference))
|
||||
requiresCoercionToUnit(resolvedDescriptor, callableReferenceType) ||
|
||||
requiresSuspendConversion(resolvedDescriptor, callableReferenceType)
|
||||
) {
|
||||
return generateAdaptedCallableReference(ktCallableReference, callBuilder)
|
||||
return generateAdaptedCallableReference(ktCallableReference, callBuilder, callableReferenceType)
|
||||
}
|
||||
|
||||
return statementGenerator.generateCallReceiver(
|
||||
@@ -91,7 +93,7 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
|
||||
).call { dispatchReceiverValue, extensionReceiverValue ->
|
||||
generateCallableReference(
|
||||
ktCallableReference,
|
||||
getTypeInferredByFrontendOrFail(ktCallableReference),
|
||||
callableReferenceType,
|
||||
callBuilder.descriptor,
|
||||
callBuilder.typeArguments
|
||||
).also { irCallableReference ->
|
||||
@@ -106,9 +108,15 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
|
||||
return KotlinBuiltIns.isUnit(ktExpectedReturnType) && !KotlinBuiltIns.isUnit(descriptor.returnType!!)
|
||||
}
|
||||
|
||||
private fun requiresSuspendConversion(descriptor: CallableDescriptor, callableReferenceType: KotlinType): Boolean =
|
||||
descriptor is FunctionDescriptor &&
|
||||
!descriptor.isSuspend &&
|
||||
callableReferenceType.isKSuspendFunctionType
|
||||
|
||||
private fun generateAdaptedCallableReference(
|
||||
ktCallableReference: KtCallableReferenceExpression,
|
||||
callBuilder: CallBuilder
|
||||
callBuilder: CallBuilder,
|
||||
callableReferenceType: KotlinType
|
||||
): IrExpression {
|
||||
val adapteeDescriptor = callBuilder.descriptor
|
||||
if (adapteeDescriptor !is FunctionDescriptor) {
|
||||
@@ -128,7 +136,7 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
|
||||
val ktExpectedParameterTypes = ktFunctionalTypeArguments.take(ktFunctionalTypeArguments.size - 1).map { it.type }
|
||||
|
||||
val irAdapterFun =
|
||||
createAdapterFun(startOffset, endOffset, adapteeDescriptor, ktExpectedParameterTypes, ktExpectedReturnType, callBuilder)
|
||||
createAdapterFun(startOffset, endOffset, adapteeDescriptor, ktExpectedParameterTypes, ktExpectedReturnType, callBuilder, callableReferenceType)
|
||||
val irCall = createAdapteeCall(startOffset, endOffset, adapteeSymbol, callBuilder, irAdapterFun)
|
||||
|
||||
irAdapterFun.body = IrBlockBodyImpl(startOffset, endOffset).apply {
|
||||
@@ -326,9 +334,13 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
|
||||
ktExpectedParameterTypes: List<KotlinType>,
|
||||
ktExpectedReturnType: KotlinType,
|
||||
callBuilder: CallBuilder,
|
||||
callableReferenceType: KotlinType
|
||||
): IrSimpleFunction {
|
||||
val adapterFunctionDescriptor = WrappedSimpleFunctionDescriptor()
|
||||
|
||||
val hasSuspendConversion = !adapteeDescriptor.isSuspend &&
|
||||
callableReferenceType.isKSuspendFunctionType
|
||||
|
||||
return context.symbolTable.declareSimpleFunction(
|
||||
startOffset, endOffset,
|
||||
IrDeclarationOrigin.ADAPTER_FOR_CALLABLE_REFERENCE,
|
||||
@@ -345,7 +357,7 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
|
||||
isInline = adapteeDescriptor.isInline, // TODO ?
|
||||
isExternal = false,
|
||||
isTailrec = false,
|
||||
isSuspend = adapteeDescriptor.isSuspend, // TODO ?
|
||||
isSuspend = adapteeDescriptor.isSuspend || hasSuspendConversion,
|
||||
isOperator = adapteeDescriptor.isOperator, // TODO ?
|
||||
isExpect = false,
|
||||
isFakeOverride = false
|
||||
|
||||
Reference in New Issue
Block a user