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.

ClassMetadataParser   A
last analyzed

Complexity

Total Complexity 25

Size/Duplication

Total Lines 135
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
wmc 25
lcom 1
cbo 6
dl 0
loc 135
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
B getClass() 0 25 6
A isTypeBuiltIn() 0 4 1
A getReturn() 0 31 5
B getFullQualifiedName() 0 28 6
A getFieldName() 0 19 6
1
<?php
2
namespace Soukicz\ClassMetadataParser;
3
4
use Doctrine\Common\Annotations\PhpParser;
5
use Doctrine\Common\Annotations\Reader;
6
use Soukicz\ClassMetadataParser\Annotation\CollectionDefinition;
7
use Soukicz\ClassMetadataParser\Model\ClassMetadata;
8
use Soukicz\ClassMetadataParser\Model\MethodMetadata;
9
use Soukicz\ClassMetadataParser\Model\ReturnMetadata;
10
11
class ClassMetadataParser
12
{
13
    /**
14
     * @var Reader
15
     */
16
    private $annotationReader;
17
18
    /**
19
     * @var PhpParser
20
     */
21
    private $phpParser;
22
23
    public function __construct(Reader $annotationReader)
24
    {
25
        $this->annotationReader = $annotationReader;
26
        $this->phpParser = new PhpParser();
27
    }
28
29
    /**
30
     * @var ClassMetadata[]
31
     */
32
    private $cache = [];
33
34
    public function getClass(string $className): ClassMetadata
35
    {
36
        if (!isset($this->cache[$className])) {
37
            $reflectionClass = new \ReflectionClass($className);
38
            $methods = [];
39
40
            $imports = $this->phpParser->parseClass($reflectionClass);
41
42
            foreach ($reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
43
                $mapping = $this->annotationReader->getMethodAnnotation($method, CollectionDefinition::class);
44
                if ($method->getName() === '__construct' || $method->isStatic()) {
45
                    continue;
46
                }
47
                $methods[$method->getName()] = new MethodMetadata(
48
                    $method->getName(),
49
                    self::getFieldName($method->getName()),
50
                    $this->getReturn($method, $imports),
51
                    $mapping instanceof CollectionDefinition ? $mapping->mapping : null
52
                );
53
            }
54
55
            $this->cache[$className] = new ClassMetadata($methods, $reflectionClass);
56
        }
57
        return $this->cache[$className];
58
    }
59
60
    private function isTypeBuiltIn(string $type)
61
    {
62
        return in_array($type, ['null', 'void', 'string', 'int', 'float', 'bool']);
63
    }
64
65
    private function getReturn(\ReflectionMethod $method, array $imports):?ReturnMetadata
66
    {
67
        $docBlock = $method->getDocComment();
68
        if (preg_match('~\s\*\s*@return\s+null\|([a-zA-Z0-9]+)(\[\])?~', $docBlock, $m)) {
69
            return new ReturnMetadata(
70
                $this->getFullQualifiedName($method, $m[1], $imports),
71
                $this->isTypeBuiltIn($m[1]),
72
                true,
73
                !empty($m[2])
74
            );
75
        } elseif (preg_match('~\s\*\s*@return\s+([a-zA-Z0-9]+)(\[\])?(\|null)?~', $docBlock, $m)) {
76
            return new ReturnMetadata(
77
                $this->getFullQualifiedName($method, $m[1], $imports),
78
                $this->isTypeBuiltIn($m[1]),
79
                !empty($m[3]),
80
                !empty($m[2])
81
            );
82
        } elseif ($method->hasReturnType()) {
83
            $type = (string)$method->getReturnType();
84
            if ($type === 'self') {
85
                $type = $method->getDeclaringClass()->getName();
86
            }
87
            return new ReturnMetadata(
88
                $type,
89
                $method->getReturnType()->isBuiltin(),
90
                $method->getReturnType()->allowsNull(),
91
                false
92
            );
93
        }
94
        return null;
95
    }
96
97
    private function getFullQualifiedName(\ReflectionMethod $method, string $alias, array $imports): string
98
    {
99
        if ($alias === 'self') {
100
            return $method->getDeclaringClass()->getName();
101
        }
102
103
        if ($this->isTypeBuiltIn($alias)) {
104
            return $alias;
105
        }
106
107
        $parts = explode('\\', $alias);
108
        $last = $parts[count($parts) - 1];
109
        $first = strtolower(array_shift($parts));
110
111
        if ($last === $method->getDeclaringClass()->getShortName()) {
112
            return $method->getDeclaringClass()->getName();
113
        }
114
115
        if (!isset($imports[$first])) {
116
            return $method->getDeclaringClass()->getNamespaceName() . '\\' . $alias;
117
        }
118
119
        $namespace = $imports[$first];
120
        if (empty($parts)) {
121
            return $namespace;
122
        }
123
        return $namespace . '\\' . implode('\\', $parts);
124
    }
125
126
    public static function getFieldName(string $methodName):?string
127
    {
128
        if (substr($methodName, 0, 3) !== 'get' && substr($methodName, 0, 3) !== 'is' ) {
129
            return null;
130
        }
131
        $name = substr($methodName, 3);
132
        $newName = '';
133
        $length = strlen($name);
134
        for ($i = 0; $i < $length; $i++) {
135
            if ($i == 0) {
136
                $newName = strtolower($name[$i]);
137
            } elseif (strtolower($name[$i]) === $name[$i]) {
138
                $newName .= $name[$i];
139
            } else {
140
                $newName .= '_' . strtolower($name[$i]);
141
            }
142
        }
143
        return $newName;
144
    }
145
}
146