GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( b68e37...36b33c )
by SignpostMarv
03:39
created

StaticMethodCollector   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 215
Duplicated Lines 0 %

Test Coverage

Coverage 92.41%

Importance

Changes 0
Metric Value
dl 0
loc 215
ccs 73
cts 79
cp 0.9241
rs 9.6
c 0
b 0
f 0
wmc 32

4 Methods

Rating   Name   Duplication   Size   Complexity  
A Collect() 0 13 3
A shouldContainInterfaces() 0 3 2
C CollectInterfaces() 0 54 15
C __construct() 0 102 12
1
<?php
2
3
declare(strict_types=1);
4
/**
5
* @author SignpostMarv
6
*/
7
8
namespace SignpostMarv\DaftInterfaceCollector;
9
10
use Generator;
11
use ReflectionClass;
12
use ReflectionMethod;
13
use Traversable;
14
15
class StaticMethodCollector
16
{
17
    /**
18
    * @var array<string, array<int, string>>
19
    */
20
    private $staticMethods;
21
22
    /**
23
    * @var string[]
24
    */
25
    private $interfaces = [];
26
27
    /**
28
    * @var array<int, string>
29
    */
30
    private $processedSources = [];
31
32
    /**
33
    * @var string[]
34
    */
35
    private $alreadyYielded = [];
36
37
    /**
38
    * @var bool
39
    */
40
    private $autoResetProcessedSources;
41
42 4
    public function __construct(
43
        array $staticMethods,
44
        array $interfaces,
45
        bool $autoResetProcessedSources = true
46
    ) {
47 4
        $staticMethods = array_filter(
48 4
            $staticMethods,
49
            /**
50
            * @param mixed $maybe
51
            */
52
            function ($maybe) : bool {
53 4
                return is_string($maybe) && interface_exists($maybe);
54 4
            },
55 4
            ARRAY_FILTER_USE_KEY
56
        );
57
58
        /**
59
        * @var array<string, array<int, string>> $filtered
60
        */
61 4
        $filtered = [];
62
63
        /**
64
        * @var string $interface
65
        * @var array<string, array<int, string>> $methods
66
        */
67 4
        foreach ($staticMethods as $interface => $methods) {
68 4
            $ref = new ReflectionClass($interface);
69
70 4
            $filtered[$interface] = array_filter(
71 4
                $methods,
72
                /**
73
                * @param mixed $maybe
74
                */
75
                function ($maybe) use ($ref) : bool {
76 4
                    if (is_string($maybe) && $ref->hasMethod($maybe)) {
77
                        /**
78
                        * @var ReflectionMethod $refMethod
79
                        */
80 4
                        $refMethod = $ref->getMethod($maybe);
81
82
                        if (
83 4
                            $refMethod->isStatic() &&
84 4
                            $refMethod->isPublic() &&
85 4
                            0 === $refMethod->getNumberOfRequiredParameters() &&
86 4
                            $refMethod->hasReturnType()
87
                        ) {
88
                            /**
89
                            * @var \ReflectionType $refReturn
90
                            */
91 4
                            $refReturn = $refMethod->getReturnType();
92
93
                            return
94 4
                                'array' === $refReturn->__toString() ||
0 ignored issues
show
Deprecated Code introduced by
The function ReflectionType::__toString() has been deprecated: 7.1.0:8.0.0 Please use getName() ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

94
                                'array' === /** @scrutinizer ignore-deprecated */ $refReturn->__toString() ||

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
95 4
                                is_a((string) $refReturn->__toString(), Traversable::class, true);
0 ignored issues
show
Deprecated Code introduced by
The function ReflectionType::__toString() has been deprecated: 7.1.0:8.0.0 Please use getName() ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

95
                                is_a((string) /** @scrutinizer ignore-deprecated */ $refReturn->__toString(), Traversable::class, true);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
96
                        }
97
                    }
98
99
                    return false;
100 4
                },
101 4
                ARRAY_FILTER_USE_KEY
102
            );
103
104 4
            $filtered[$interface] = array_map(
105
                function (array $methodInterfaces) : array {
106 4
                    return array_filter(
107 4
                        $methodInterfaces,
108
                        /**
109
                        * @param mixed $maybe
110
                        */
111
                        function ($maybe) : bool {
112 4
                            return is_string($maybe) && interface_exists($maybe);
113 4
                        }
114
                    );
115 4
                },
116 4
                $filtered[$interface]
117
            );
118
        }
119
120
        /**
121
        * @var array<string, array<int, string>> $filtered
122
        */
123
        $filtered = array_filter($filtered, function (array $methods) : bool {
124 4
            return count($methods) > 0;
125 4
        });
126
127
        /**
128
        * @var string[] $filteredInterfaces
129
        */
130 4
        $filteredInterfaces = array_filter(
131 4
            $interfaces,
132
            /**
133
            * @param mixed $maybe
134
            */
135
            function ($maybe) : bool {
136 4
                return is_string($maybe) && interface_exists($maybe);
137 4
            }
138
        );
139
140 4
        $this->interfaces = $filteredInterfaces;
141
142 4
        $this->staticMethods = $filtered;
143 4
        $this->autoResetProcessedSources = $autoResetProcessedSources;
144 4
    }
145
146 4
    public function Collect(string ...$implementations) : Generator
147
    {
148 4
        if ($this->autoResetProcessedSources) {
149 2
            $this->processedSources = [];
150 2
            $this->alreadyYielded = [];
151
        }
152
153 4
        if ($this->autoResetProcessedSources) {
154 2
            $this->processedSources = [];
155 2
            $this->alreadyYielded = [];
156
        }
157
158 4
        yield from $this->CollectInterfaces(...$implementations);
159 4
    }
160
161 4
    protected function CollectInterfaces(string ...$implementations) : Generator
162
    {
163
        /**
164
        * @var string[] $interfaces
165
        */
166 4
        $interfaces = array_keys($this->staticMethods);
167 4
        foreach (array_filter($implementations, 'class_exists') as $implementation) {
168
            if (
169 4
                in_array($implementation, $this->processedSources, true) ||
170 4
                in_array($implementation, $this->alreadyYielded, true)
171
            ) {
172 2
                continue;
173
            }
174 4
            $this->processedSources[] = $implementation;
175
176
            /**
177
            * @var string $interface
178
            */
179 4
            foreach ($this->interfaces as $interface) {
180 4
                if (is_a($implementation, $interface, true)) {
181
                    yield $implementation;
182
                    $this->alreadyYielded[] = $implementation;
183 4
                    break;
184
                }
185
            }
186
187 4
            foreach ($interfaces as $interface) {
188 4
                if (is_a($implementation, $interface, true)) {
189
                    /**
190
                    * @var string[] $types
191
                    */
192 4
                    foreach ($this->staticMethods[$interface] as $method => $types) {
193
                        /**
194
                        * @var iterable<string> $methodResult
195
                        */
196 4
                        $methodResult = $implementation::$method();
197
198
                        /**
199
                        * @var string $result
200
                        */
201 4
                        foreach ($methodResult as $result) {
202 4
                            if (in_array($result, $this->alreadyYielded, true)) {
203
                                continue;
204
                            }
205 4
                            foreach ($types as $type) {
0 ignored issues
show
Bug introduced by
The expression $types of type string is not traversable.
Loading history...
206 4
                                if (is_a($result, $type, true)) {
207 4
                                    yield $result;
208 4
                                    $this->alreadyYielded[] = $result;
209 4
                                    continue;
210
                                }
211
                            }
212 4
                            foreach ($interfaces as $checkResultWithInterface) {
213 4
                                if (is_a($result, $checkResultWithInterface, true)) {
214 4
                                    yield from $this->CollectInterfaces($result);
215
                                }
216
                            }
217
                        }
218
                    }
219
                }
220
            }
221
        }
222 4
    }
223
224
    /**
225
    * @param mixed $maybe
226
    */
227
    protected function shouldContainInterfaces($maybe) : bool
228
    {
229
        return is_string($maybe) && interface_exists($maybe);
230
    }
231
}
232