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 ( f06180...d17a44 )
by SignpostMarv
06:19
created

DefinitionAssistant::AutoRegisterType()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 1
1
<?php
2
/**
3
* @author SignpostMarv
4
*/
5
declare(strict_types=1);
6
7
namespace SignpostMarv\DaftObject;
8
9
use Closure;
10
use InvalidArgumentException;
11
use SignpostMarv\DaftMagicPropertyAnalysis\DefinitionAssistant as Base;
12
13
/**
14
* @template-extends Base<DaftObject>
15
*/
16
class DefinitionAssistant extends Base
17
{
18
    const BOOL_EXPECTING_GETTER = false;
19
20
    const BOOL_EXPECTING_SETTER = true;
21
22
    const INT_ARRAY_INDEX_TYPE = 0;
23
24
    const INT_ARRAY_INDEX_GETTER = 1;
25
26
    const INT_ARRAY_INDEX_SETTER = 2;
27
28
    const IS_A_STRINGS = true;
29
30 46
    public static function IsTypeUnregistered(string $type) : bool
31
    {
32 46
        if ( ! is_a($type, DaftObject::class, true)) {
33 4
            throw new InvalidArgumentException(
34
                'Argument 1 passed to ' .
35
                __METHOD__ .
36
                '() must be an implementation of ' .
37
                DaftObject::class .
38
                ', ' .
39 4
                $type .
40 4
                ' given!'
41
            );
42
        }
43
44 42
        return parent::IsTypeUnregistered($type);
45
    }
46
47
    /**
48
    * @psalm-param class-string<AbstractDaftObject> $maybe
49
    */
50 36
    public static function RegisterAbstractDaftObjectType(string $maybe) : void
51
    {
52
        /**
53
        * @var array<int, string>
54
        */
55 36
        $props = TypeCertainty::EnsureArgumentIsArray($maybe::PROPERTIES);
56
57 36
        static::RegisterDaftObjectTypeFromTypeAndProps($maybe, ...$props);
58 36
    }
59
60 38
    public static function ObtainExpectedProperties($maybe) : array
61
    {
62 38
        $maybe = is_object($maybe) ? get_class($maybe) : $maybe;
63
64 38
        if (static::IsTypeUnregistered($maybe)) {
65 34
            if (is_a($maybe, AbstractDaftObject::class, self::IS_A_STRINGS)) {
66 34
                static::RegisterAbstractDaftObjectType($maybe);
67
            }
68
        }
69
70 36
        $maybe = self::MaybeRegisterAdditionalTypes($maybe);
71
72 36
        return parent::ObtainExpectedProperties($maybe);
73
    }
74
75
    /**
76
    * @psalm-param class-string<DaftObject> $type
77
    */
78 4
    public static function AutoRegisterType(string $type, string ...$properties) : void
79
    {
80 4
        static::RegisterDaftObjectTypeFromTypeAndProps($type, ...$properties);
81 4
    }
82
83
    /**
84
    * @psalm-return Closure(string):?string
85
    */
86 38
    public static function SetterOrGetterClosure(
87
        string $type,
88
        bool $SetNotGet,
89
        string ...$props
90
    ) : Closure {
91
        return function (string $property) use ($type, $props, $SetNotGet) : ? string {
92 4
            if (in_array($property, $props, self::IN_ARRAY_STRICT_MODE)) {
93
                /**
94
                * @var string
95
                */
96 4
                $method = TypeUtilities::MethodNameFromProperty($property, $SetNotGet);
97
98 4
                if (method_exists($type, $method)) {
99 4
                    return $method;
100
                }
101
            }
102
103 2
            return null;
104 38
        };
105
    }
106
107
    /**
108
    * @param mixed $value
109
    *
110
    * @return array<int, mixed> filtered $value
111
    */
112 14
    public static function MaybeThrowIfValueDoesNotMatchMultiTypedArray(
113
        bool $autoTrimStrings,
114
        bool $throwIfNotUnique,
115
        $value,
116
        string ...$types
117
    ) : array {
118 14
        if ( ! is_array($value)) {
119 2
            throw new InvalidArgumentException(
120
                'Argument 3 passed to ' .
121
                __METHOD__ .
122
                ' must be an array, ' .
123 2
                (is_object($value) ? get_class($value) : gettype($value)) .
124 2
                ' given!'
125
            );
126
        }
127
128 12
        return static::MaybeThrowIfValueDoesNotMatchMultiTypedArrayValueArray(
129 12
            $autoTrimStrings,
130 12
            $throwIfNotUnique,
131 12
            $value,
132 9
            ...$types
133
        );
134
    }
135
136
    /**
137
    * @psalm-param class-string<DaftObject> $type
138
    *
139
    * @psalm-return array{0:class-string<DaftObject>, 1:null|Closure(string):?string, 2:null|Closure(string):?string, 4:string}
140
    */
141 38
    private static function TypeAndGetterAndSetterClosureWithProps(
142
        string $type,
143
        string ...$props
144
    ) : array {
145
        /**
146
        * @psalm-var array{0:class-string<DaftObject>, 1:null|Closure(string):?string, 2:null|Closure(string):?string, 4:string}
147
        */
148 38
        $out = array_merge(
149
            [
150 38
                $type,
151 38
                static::SetterOrGetterClosure($type, self::BOOL_EXPECTING_GETTER, ...$props),
152 38
                static::SetterOrGetterClosure($type, self::BOOL_EXPECTING_SETTER, ...$props),
153
            ],
154 38
            $props
155
        );
156
157 38
        return $out;
158
    }
159
160
    /**
161
    * @psalm-param class-string<DaftObject> $maybe
162
    */
163 38
    private static function RegisterDaftObjectTypeFromTypeAndProps(
164
        string $maybe,
165
        string ...$props
166
    ) : void {
167 38
        $args = static::TypeAndGetterAndSetterClosureWithProps($maybe, ...$props);
168
169
        /**
170
        * @var array<int, string>
171
        */
172 38
        $props = array_slice($args, 3);
173
174 38
        static::RegisterType(
175 38
            $args[self::INT_ARRAY_INDEX_TYPE],
176 38
            $args[self::INT_ARRAY_INDEX_GETTER],
177 38
            $args[self::INT_ARRAY_INDEX_SETTER],
178 19
            ...$props
179
        );
180 38
        self::MaybeRegisterAdditionalTypes($args[0]);
181 38
    }
182
183
    /**
184
    * @psalm-param class-string<DaftObject> $maybe
185
    *
186
    * @psalm-return class-string<DaftObject>
187
    */
188 38
    private static function MaybeRegisterAdditionalTypes(string $maybe) : string
189
    {
190
        foreach (
191
            [
192 38
                DefinesOwnArrayIdInterface::class,
193
                DefinesOwnIntegerIdInterface::class,
194
                DefinesOwnStringIdInterface::class,
195
            ] as $otherType
196
        ) {
197 38
            if ($otherType !== $maybe && self::IsTypeUnregistered($otherType)) {
198 38
                self::RegisterDaftObjectTypeFromTypeAndProps($otherType, 'id');
199
            }
200
        }
201
202 38
        return $maybe;
203
    }
204
205
    /**
206
    * @return array<int, mixed> filtered $value
207
    */
208 12
    private static function MaybeThrowIfValueDoesNotMatchMultiTypedArrayValueArray(
209
        bool $autoTrimStrings,
210
        bool $throwIfNotUnique,
211
        array $value,
212
        string ...$types
213
    ) : array {
214 12
        $value = static::MaybeThrowIfNotArrayIntKeys($value);
215 10
        $value = static::MaybeThrowIfValueArrayDoesNotMatchTypes($value, ...$types);
216 8
        $value = static::MaybeRemapStringsToTrimmedStrings($value, $autoTrimStrings, ...$types);
217
218 8
        $initialCount = count($value);
219
220 8
        $value = array_unique($value, SORT_REGULAR);
221
222 8
        if ($throwIfNotUnique && count($value) !== $initialCount) {
223 2
            throw new InvalidArgumentException(
224
                'Argument 3 passed to ' .
225
                __METHOD__ .
226 2
                ' contained non-unique values!'
227
            );
228
        }
229
230 6
        return array_values($value);
231
    }
232
233
    /**
234
    * @return array<int, mixed> filtered $value
235
    */
236 12
    private static function MaybeThrowIfNotArrayIntKeys(array $value) : array
237
    {
238 12
        $initialCount = count($value);
239
240
        /**
241
        * @var array<int, mixed>
242
        */
243 12
        $value = array_filter($value, 'is_int', ARRAY_FILTER_USE_KEY);
244
245 12
        if (count($value) !== $initialCount) {
246 2
            throw new InvalidArgumentException(
247
                'Argument 3 passed to ' .
248
                __METHOD__ .
249 2
                ' must be array<int, mixed>'
250
            );
251
        }
252
253 10
        return $value;
254
    }
255
256
    /**
257
    * @param array<int, mixed> $value
258
    *
259
    * @return array<int, mixed> filtered $value
260
    */
261 10
    private static function MaybeThrowIfValueArrayDoesNotMatchTypes(
262
        array $value,
263
        string ...$types
264
    ) : array {
265 10
        $initialCount = count($value);
266
267 10
        $value = array_filter(
268 10
            $value,
269
            /**
270
            * @param mixed $maybe
271
            */
272
            function ($maybe) use ($types) : bool {
273 10
                if (is_object($maybe)) {
274 8
                    foreach ($types as $maybeType) {
275 8
                        if (is_a($maybe, $maybeType)) {
276 8
                            return true;
277
                        }
278
                    }
279
280 2
                    return false;
281
                }
282
283 4
                return in_array(
284 4
                    gettype($maybe),
285 4
                    $types,
286 4
                    DefinitionAssistant::IN_ARRAY_STRICT_MODE
287
                );
288 10
            }
289
        );
290
291 10
        if (count($value) !== $initialCount) {
292 2
            throw new InvalidArgumentException(
293
                'Argument 3 passed to ' .
294
                __METHOD__ .
295 2
                ' contained values that did not match the provided types!'
296
            );
297
        }
298
299 8
        return $value;
300
    }
301
302
    /**
303
    * @param array<int, mixed> $value
304
    *
305
    * @return array<int, mixed>
306
    */
307 8
    private static function MaybeRemapStringsToTrimmedStrings(
308
        array $value,
309
        bool $autoTrimStrings,
310
        string ...$types
311
    ) : array {
312
        if (
313 8
            $autoTrimStrings &&
314 8
            in_array('string', $types, DefinitionAssistant::IN_ARRAY_STRICT_MODE)
315
        ) {
316 2
            $value = array_map(
317
                /**
318
                * @param mixed $maybe
319
                *
320
                * @return mixed
321
                */
322
                function ($maybe) {
323 2
                    return is_string($maybe) ? trim($maybe) : $maybe;
324 2
                },
325 2
                $value
326
            );
327
        }
328
329 8
        return $value;
330
    }
331
}
332