src/Language/Visitor.php
public static function getVisitFn($visitor, $kind, $isLeaving)
    {
        if ($visitor === null) {
            return null;
        }

        $kindVisitor = $visitor[$kind] ?? null;

        if (! $isLeaving && is_callable($kindVisitor)) {
            // { Kind() {} }
            return $kindVisitor;
        }

        if (is_array($kindVisitor)) {
            if ($isLeaving) {
                $kindSpecificVisitor = $kindVisitor['leave'] ?? null;
            } else {
                $kindSpecificVisitor = $kindVisitor['enter'] ?? null;
            }

            if ($kindSpecificVisitor && is_callable($kindSpecificVisitor)) {
                // { Kind: { enter() {}, leave() {} } }
                return $kindSpecificVisitor;
            }

            return null;
        }

        $visitor += ['leave' => null, 'enter' => null];

        $specificVisitor = $isLeaving ? $visitor['leave'] : $visitor['enter'];

        if ($specificVisitor) {
            if (is_callable($specificVisitor)) {
                // { enter() {}, leave() {} }
                return $specificVisitor;
            }
            $specificKindVisitor = $specificVisitor[$kind] ?? null;

            if (is_callable($specificKindVisitor)) {
                // { enter: { Kind() {} }, leave: { Kind() {} } }
                return $specificKindVisitor;
            }
        }

        return null;
    }
public static function getVisitFn($visitor, $kind, $isLeaving)
    {
        if ($visitor === null) {
            return null;
        }

        $kindVisitor = $visitor[$kind] ?? null;

        if (! $isLeaving && is_callable($kindVisitor)) {
            // { Kind() {} }
            return $kindVisitor;
        }

        if (is_array($kindVisitor)) {
            if ($isLeaving) {
                $kindSpecificVisitor = $kindVisitor['leave'] ?? null;
            } else {
                $kindSpecificVisitor = $kindVisitor['enter'] ?? null;
            }

            if ($kindSpecificVisitor && is_callable($kindSpecificVisitor)) {
                // { Kind: { enter() {}, leave() {} } }
                return $kindSpecificVisitor;
            }

            return null;
        }

        $visitor += ['leave' => null, 'enter' => null];

        $specificVisitor = $isLeaving ? $visitor['leave'] : $visitor['enter'];

        if ($specificVisitor) {
            if (is_callable($specificVisitor)) {
                // { enter() {}, leave() {} }
                return $specificVisitor;
            }
            $specificKindVisitor = $specificVisitor[$kind] ?? null;

            if (is_callable($specificKindVisitor)) {
                // { enter: { Kind() {} }, leave: { Kind() {} } }
                return $specificKindVisitor;
            }
        }

        return null;
    }
@param callable[]|null $visitor
@param string          $kind
@param bool            $isLeaving

@return callable|null