ClassFunctionExtractorTrait.php

Code Hygiene Score: 100

Keine Issues gefunden.

Klassen 1

Funktionen 3

Verwendet von 1

Code

<?php

declare(strict_types=1);

namespace Infrastructure\CodeAnalysis;

// @responsibility: Extraktion von Klassen/Interfaces/Traits und Funktionen

/**
 * Trait for extracting class and function definitions from PHP token arrays.
 */
trait ClassFunctionExtractorTrait
{
    /**
     * Extract class/interface/trait/enum definitions.
     *
     * @param array<mixed> $tokens
     * @return array<array{name: string, type: string, line: int}>
     */
    private function extractClasses(array $tokens): array
    {
        $classes = [];
        $count = count($tokens);

        for ($i = 0; $i < $count; $i++) {
            $token = $tokens[$i];

            if (!is_array($token)) {
                continue;
            }

            $type = match ($token[0]) {
                T_CLASS => 'class',
                T_INTERFACE => 'interface',
                T_TRAIT => 'trait',
                T_ENUM => 'enum',
                default => null,
            };

            if ($type === null) {
                continue;
            }

            // Skip anonymous class statements
            $prevIndex = $this->findPrevNonWhitespace($tokens, $i);
            if ($prevIndex !== null && is_array($tokens[$prevIndex]) && $tokens[$prevIndex][0] === T_NEW) {
                continue;
            }

            // Find class name
            for ($j = $i + 1; $j < $count; $j++) {
                if (is_array($tokens[$j]) && $tokens[$j][0] === T_STRING) {
                    $classes[] = [
                        'name' => $tokens[$j][1],
                        'type' => $type,
                        'line' => $token[2],
                    ];

                    break;
                }
            }
        }

        return $classes;
    }

    /**
     * Extract function/method definitions.
     *
     * @param array<mixed> $tokens
     * @return array<array{name: string, visibility: string|null, line: int}>
     */
    private function extractFunctions(array $tokens): array
    {
        $functions = [];
        $count = count($tokens);
        $braceDepth = 0;
        $inClass = false;

        for ($i = 0; $i < $count; $i++) {
            $token = $tokens[$i];

            if (!is_array($token)) {
                if ($token === '{') {
                    $braceDepth++;
                } elseif ($token === '}') {
                    $braceDepth--;
                    if ($braceDepth === 0) {
                        $inClass = false;
                    }
                }

                continue;
            }

            if (in_array($token[0], [T_CLASS, T_INTERFACE, T_TRAIT, T_ENUM], true)) {
                $inClass = true;
            }

            if ($token[0] !== T_FUNCTION) {
                continue;
            }

            $visibility = null;
            if ($inClass) {
                for ($j = $i - 1; $j >= 0; $j--) {
                    if (!is_array($tokens[$j])) {
                        break;
                    }
                    if ($tokens[$j][0] === T_PUBLIC) {
                        $visibility = 'public';

                        break;
                    }
                    if ($tokens[$j][0] === T_PROTECTED) {
                        $visibility = 'protected';

                        break;
                    }
                    if ($tokens[$j][0] === T_PRIVATE) {
                        $visibility = 'private';

                        break;
                    }
                    if ($tokens[$j][0] !== T_WHITESPACE && $tokens[$j][0] !== T_STATIC && $tokens[$j][0] !== T_FINAL && $tokens[$j][0] !== T_ABSTRACT) {
                        break;
                    }
                }
            }

            for ($j = $i + 1; $j < $count; $j++) {
                if (is_array($tokens[$j]) && $tokens[$j][0] === T_STRING) {
                    $functions[] = [
                        'name' => $tokens[$j][1],
                        'visibility' => $visibility,
                        'line' => $token[2],
                    ];

                    break;
                }
                if ($tokens[$j] === '(') {
                    break;
                }
            }
        }

        return $functions;
    }

    /**
     * Required from TokenNavigatorTrait.
     *
     * @param array<mixed> $tokens
     */
    abstract private function findPrevNonWhitespace(array $tokens, int $index): ?int;
}
← Übersicht Graph