Reflector   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 61
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 1
Metric Value
eloc 37
c 3
b 0
f 1
dl 0
loc 61
rs 10
wmc 18

2 Methods

Rating   Name   Duplication   Size   Complexity  
C getTypeHint() 0 43 14
A matchType() 0 14 4
1
<?php
2
declare(strict_types=1);
3
4
namespace BrenoRoosevelt\PhpAttributes\Specification;
5
6
use ReflectionClass;
7
use ReflectionClassConstant;
8
use ReflectionFunctionAbstract;
9
use ReflectionMethod;
10
use ReflectionNamedType;
11
use ReflectionParameter;
12
use ReflectionProperty;
13
use ReflectionType;
14
use ReflectionUnionType;
15
16
class Reflector
17
{
18
    public static function getTypeHint(\Reflector $subject): array
19
    {
20
        if ($subject instanceof ReflectionFunctionAbstract) {
21
            $type = $subject->getReturnType();
22
        } elseif ($subject instanceof ReflectionParameter) {
23
            $type = $subject->getType();
24
        } elseif ($subject instanceof ReflectionProperty) {
25
            $type = $subject->getType();
26
        } elseif ($subject instanceof ReflectionClassConstant) {
27
            return [gettype($subject->getValue())];
28
        } elseif ($subject instanceof ReflectionClass) {
29
            return [$subject->getName()];
30
        } else {
31
            return [];
32
        }
33
34
        $types = [];
35
        $result = [];
36
37
        if ($type instanceof ReflectionNamedType) {
38
            $types[] = $type;
39
        } elseif ($type instanceof ReflectionUnionType) {
40
            $types = $type->getTypes();
41
        }
42
43
        foreach ($types as $type) {
44
            if ($type->allowsNull()) {
45
                $result[] = 'null';
46
            }
47
48
            $typeHint = ltrim($type->getName(), "?");
49
            if ($typeHint === 'self' &&
50
                ($subject instanceof ReflectionMethod ||
51
                $subject instanceof ReflectionProperty ||
52
                $subject instanceof ReflectionParameter)
53
            ) {
54
                $typeHint = $subject->getDeclaringClass()->getName();
55
            }
56
57
            $result[] = $typeHint;
58
        }
59
60
        return $result;
61
    }
62
63
    public static function matchType(\Reflector $subject, string $type): bool
64
    {
65
        $types = Reflector::getTypeHint($subject);
66
        if (in_array($type, $types, true)) {
67
            return true;
68
        }
69
70
        foreach ($types as $typeHint) {
71
            if (is_a($typeHint, $type, true)) {
72
                return true;
73
            }
74
        }
75
76
        return false;
77
    }
78
}
79