protected function getJoinpointInvocationBody(ReflectionFunction $function): string
    {
        $class = '\\' . __CLASS__;

        $argumentList = new FunctionCallArgumentListGenerator($function);
        $argumentCode = $argumentList->generate();

        $return = 'return ';
        if ($function->hasReturnType()) {
            $returnType = (string) $function->getReturnType();
            if ($returnType === 'void') {
                // void return types should not return anything
                $return = '';
            }
        }

        $functionAdvices = $this->advices[AspectContainer::FUNCTION_PREFIX][$function->name];
        $advicesArray    = new ValueGenerator($functionAdvices, ValueGenerator::TYPE_ARRAY_SHORT);
        $advicesArray->setArrayDepth(1);
        $advicesCode = $advicesArray->generate();

        return <<<BODY
static \$__joinPoint;
if (\$__joinPoint === null) {
    \$__joinPoint = {$class}::getJoinPoint('{$function->name}', {$advicesCode});
}
{$return}\$__joinPoint->__invoke($argumentCode);
BODY;
    }