Passed
Pull Request — master (#38)
by Sergei
05:23 queued 02:36
created

NativeClassifier::getAvailableDeclarations()   B

Complexity

Conditions 7
Paths 18

Size

Total Lines 39
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 7

Importance

Changes 0
Metric Value
cc 7
eloc 18
c 0
b 0
f 0
nc 18
nop 0
dl 0
loc 39
ccs 18
cts 18
cp 1
crap 7
rs 8.8333
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Classifier;
6
7
/**
8
 * `NativeClassifier` is a classifier that finds classes, interfaces, traits and enums using PHP's native functions:
9
 * - {@see get_declared_classes()}
10
 * - {@see get_declared_interfaces()}
11
 * - {@see get_declared_traits()}
12
 */
13
final class NativeClassifier extends AbstractClassifier
14
{
15
    /**
16
     * @psalm-suppress UnresolvableInclude
17
     */
18 17
    protected function getAvailableDeclarations(): iterable
19
    {
20 17
        $files = $this->getFiles();
21
22 17
        foreach ($files as $file) {
23
            try {
24 17
                require_once $file;
25 1
            } catch (\Throwable) {
26
                // Ignore syntax errors
27
            }
28
        }
29
30
        /** @var string[] $declarations */
31 17
        $declarations = [...get_declared_classes(), ...get_declared_interfaces(), ...get_declared_traits()];
32
33 17
        $directories = $this->directories;
34 17
        $isWindows = DIRECTORY_SEPARATOR === '\\';
35
36 17
        if ($isWindows) {
37
            /**
38
             * @psalm-var string[] $directories
39
             */
40
            // @codeCoverageIgnoreStart
41
            $directories = str_replace('/', '\\', $directories);
42
            // @codeCoverageIgnoreEnd
43
        }
44
45 17
        foreach ($declarations as $declaration) {
46 17
            $reflectionClass = self::$reflectionsCache[$declaration] ??= new \ReflectionClass($declaration);
47
48 17
            $matchedDirs = array_filter(
49 17
                $directories,
50 17
                static fn($directory) => $reflectionClass->getFileName() && str_starts_with($reflectionClass->getFileName(), $directory)
51 17
            );
52
53 17
            if (count($matchedDirs) === 0) {
54 17
                continue;
55
            }
56 17
            yield $reflectionClass->getName();
57
        }
58
    }
59
}
60