MethodAnnotations::existing()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 11
ccs 6
cts 6
cp 1
crap 2
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Cerbero\Enum\Services;
6
7
use ArrayIterator;
8
use Cerbero\Enum\Data\MethodAnnotation;
9
use IteratorAggregate;
10
use Traversable;
11
use UnitEnum;
0 ignored issues
show
Bug introduced by
The type UnitEnum was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
13
use function Cerbero\Enum\commonType;
14
15
/**
16
 * The method annotations collector.
17
 *
18
 * @implements IteratorAggregate<string, MethodAnnotation>
19
 */
20
class MethodAnnotations implements IteratorAggregate
21
{
22
    /**
23
     * The regular expression to extract method annotations already annotated on the enum.
24
     *
25
     * @var string
26
     */
27
    public const RE_METHOD = '~@method\s+((?:static)?\s*[^\s]+\s+([^\(]+).*)~';
28
29
    /**
30
     * Instantiate the class.
31
     *
32
     * @param Inspector<UnitEnum> $inspector
33
     */
34 5
    public function __construct(
35
        protected Inspector $inspector,
36
        protected bool $includeExisting,
37 5
    ) {}
38
39
    /**
40
     * Retrieve the sorted, iterable method annotations.
41
     *
42
     * @return ArrayIterator<string, MethodAnnotation>
43
     */
44 5
    public function getIterator(): Traversable
45
    {
46 5
        $annotations = $this->all();
47
48 5
        uasort($annotations, function (MethodAnnotation $a, MethodAnnotation $b) {
49 4
            return [$b->isStatic, $a->name] <=> [$a->isStatic, $b->name];
50 5
        });
51
52 5
        return new ArrayIterator($annotations);
53
    }
54
55
    /**
56
     * Retrieve all the method annotations.
57
     *
58
     * @return array<string, MethodAnnotation>
59
     */
60 5
    public function all(): array
61
    {
62 5
        return [
63 5
            ...$this->forCaseNames(),
64 5
            ...$this->forMetaAttributes(),
65 5
            ...$this->includeExisting ? $this->existing() : [],
66 5
        ];
67
    }
68
69
    /**
70
     * Retrieve the method annotations for the case names.
71
     *
72
     * @return array<string, MethodAnnotation>
73
     */
74 5
    public function forCaseNames(): array
75
    {
76 5
        $annotations = [];
77
78 5
        foreach ($this->inspector->cases() as $case) {
79 4
            $annotations[$case->name] = MethodAnnotation::forCase($case);
80
        }
81
82 5
        return $annotations;
83
    }
84
85
    /**
86
     * Retrieve the method annotations for the meta attributes.
87
     *
88
     * @return array<string, MethodAnnotation>
89
     */
90 5
    public function forMetaAttributes(): array
91
    {
92 5
        $annotations = [];
93 5
        $cases = $this->inspector->cases();
94
95 5
        foreach ($this->inspector->metaAttributeNames() as $meta) {
96 4
            $types = array_map(fn(UnitEnum $case) => get_debug_type($case->resolveMetaAttribute($meta)), $cases);
97
98 4
            $annotations[$meta] = MethodAnnotation::instance($meta, commonType(...$types));
99
        }
100
101 5
        return $annotations;
102
    }
103
104
    /**
105
     * Retrieve the method annotations already annotated on the enum.
106
     *
107
     * @return array<string, MethodAnnotation>
108
     */
109 4
    public function existing(): array
110
    {
111 4
        $annotations = [];
112
113 4
        preg_match_all(static::RE_METHOD, $this->inspector->docBlock(), $matches, PREG_SET_ORDER);
114
115 4
        foreach ($matches as $match) {
116 1
            $annotations[$match[2]] = new MethodAnnotation($match[2], $match[1]);
117
        }
118
119 4
        return $annotations;
120
    }
121
}
122