All Downloads are FREE. Search and download functionalities are using the official Maven repository.

main.seskar.compiler.suspend.backend.findAsyncFunctionSymbol.kt Maven / Gradle / Ivy

There is a newer version: 3.32.0
Show newest version
package seskar.compiler.suspend.backend

import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.ir.util.functions
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.Name

internal fun findAsyncFunctionSymbol(
    context: IrPluginContext,
    function: IrFunction,
): IrSimpleFunctionSymbol {
    val parent = function.parent
    val asyncName = Name.identifier(function.name.identifier + "Async")
    val parameterCount = function.valueParameters.size

    return when (parent) {
        is IrFile -> {
            val functionId = CallableId(
                packageName = parent.packageFqName,
                callableName = asyncName,
            )

            context.referenceFunctions(functionId)
                .asSequence()
                .filter { it.owner.isExternal }
                .filter { !it.owner.isSuspend }
                .filter { it.owner.valueParameters.size >= parameterCount }
                .sortedBy { it.owner.valueParameters.size }
                .firstOrNull()
                ?: error("Unable to find async companion for function ${function.fqNameWhenAvailable}")
        }

        is IrClass -> {
            val asyncFunction = parent.functions
                .filter { !it.isSuspend }
                .filter { it.name == asyncName }
                .filter { it.valueParameters.size >= parameterCount }
                .sortedBy { it.valueParameters.size }
                .firstOrNull()
                ?: error("Unable to find async companion for function ${function.fqNameWhenAvailable}")

            asyncFunction.symbol
        }

        else -> error("Unable to find async function for parent ${parent::class.simpleName}")
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy