override fun onMethodCallReturn()

in src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/ManagedStrategy.kt [1824:1884]


    override fun onMethodCallReturn(
        threadDescriptor: ThreadDescriptor,
        methodId: Int,
        receiver: Any?,
        params: Array<Any?>,
        result: Any?,
        interceptor: ResultInterceptor?,
    ): Unit = threadDescriptor.runInsideIgnoredSection {
        val methodDescriptor = context.getMethodDescriptor(methodId)

        // process intrinsic candidate methods
        if (methodDescriptor.isIntrinsic) {
            processIntrinsicMethodEffects(threadDescriptor, methodId, result)
        }

        val deterministicMethodDescriptor = interceptor?.getDeterministicMethodDescriptor()
        if (deterministicMethodDescriptor != null) {
            deterministicMethodDescriptor.processDeterministicMethodResult(receiver, params, result, interceptor)    
        }

        val threadId = threadScheduler.getCurrentThreadId()
        // check if the called method is an atomics API method
        // (e.g., Atomic classes, AFU, VarHandle memory access API, etc.)
        val atomicMethodDescriptor = getAtomicMethodDescriptor(receiver, methodDescriptor.methodName)
        // get method's analysis section type
        val methodSection = methodAnalysisSectionType(
            receiver,
            methodDescriptor.className,
            methodDescriptor.methodName,
            atomicMethodDescriptor,
            deterministicMethodDescriptor,
        )
        if (collectTrace && methodSection != AnalysisSectionType.IGNORED) {
            // an empty stack trace case is possible and can occur when we resume the coroutine,
            // and it results in a call to a top-level actor `suspend` function;
            // currently top-level actor functions are not represented in the `callStackTrace`,
            // we should probably refactor and fix that, because it is very inconvenient
            if (callStackTrace[threadId]!!.isNotEmpty()) {
                val tracePoint = callStackTrace[threadId]!!.last().tracePoint
                when {
                    result == Unit -> tracePoint.initializeVoidReturnedValue()
                    result == Injections.VOID_RESULT -> tracePoint.initializeVoidReturnedValue()
                    result == COROUTINE_SUSPENDED && isSuspendFunction(
                        methodDescriptor.className,
                        methodDescriptor.methodName,
                        params.asList()
                    ) ->
                        tracePoint.initializeCoroutineSuspendedResult()

                    else -> tracePoint.initializeReturnedValue(
                        objectTracker.getObjectRepresentation(result),
                        objectFqTypeName(result)
                    )
                }
                afterMethodCall(threadId, tracePoint)
                traceCollector?.addStateRepresentation()
            }
        }
        // if the method has certain guarantees, leave the corresponding section
        leaveAnalysisSection(threadId, methodSection)
    }