Passed
Push — master ( 4b5a85...fa5906 )
by Rustam
02:30
created

ClassConfigFactory   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 125
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 65
dl 0
loc 125
ccs 67
cts 67
cp 1
rs 10
c 2
b 0
f 0
wmc 18

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getMethodParameterConfigs() 0 8 2
A getMethodParameterConfig() 0 16 4
A getClassConfig() 0 17 2
A getMethodConfig() 0 7 1
A getMethodConfigs() 0 8 2
A getUnionType() 0 8 1
A getMethodTypeConfig() 0 17 3
A getMethodParameterTypeConfig() 0 17 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Proxy;
6
7
use InvalidArgumentException;
8
use Reflection;
9
use ReflectionClass;
10
use ReflectionException;
11
use ReflectionMethod;
12
use ReflectionNamedType;
13
use ReflectionParameter;
14
use ReflectionUnionType;
15
use Yiisoft\Proxy\Config\ClassConfig;
16
use Yiisoft\Proxy\Config\MethodConfig;
17
use Yiisoft\Proxy\Config\ParameterConfig;
18
use Yiisoft\Proxy\Config\TypeConfig;
19
20
final class ClassConfigFactory
21
{
22 8
    public function getClassConfig(string $interfaceName): ClassConfig
23
    {
24
        try {
25 8
            $reflection = new ReflectionClass($interfaceName);
26 1
        } catch (ReflectionException) {
27 1
            throw new InvalidArgumentException("$interfaceName must exist.");
28
        }
29
30 7
        return new ClassConfig(
31 7
            isInterface: $reflection->isInterface(),
32 7
            namespace: $reflection->getNamespaceName(),
33 7
            modifiers: Reflection::getModifierNames($reflection->getModifiers()),
34 7
            name: $reflection->getName(),
35 7
            shortName: $reflection->getShortName(),
36 7
            parent: (string) $reflection->getParentClass(),
37 7
            interfaces: $reflection->getInterfaceNames(),
38 7
            methods: $this->getMethodConfigs($reflection),
39
        );
40
    }
41
42
    /**
43
     * @return MethodConfig[]
44
     */
45 7
    private function getMethodConfigs(ReflectionClass $reflection): array
46
    {
47 7
        $methods = [];
48 7
        foreach ($reflection->getMethods() as $method) {
49 7
            $methods[$method->getName()] = $this->getMethodConfig($method);
50
        }
51
52 7
        return $methods;
53
    }
54
55 7
    private function getMethodConfig(ReflectionMethod $method): MethodConfig
56
    {
57 7
        return new MethodConfig(
58 7
            modifiers: Reflection::getModifierNames($method->getModifiers()),
59 7
            name: $method->getName(),
60 7
            parameters: $this->getMethodParameterConfigs($method),
61 7
            returnType: $this->getMethodTypeConfig($method),
62
        );
63
    }
64
65
    /**
66
     * @return ParameterConfig[]
67
     */
68 7
    private function getMethodParameterConfigs(ReflectionMethod $method): array
69
    {
70 7
        $parameters = [];
71 7
        foreach ($method->getParameters() as $param) {
72 5
            $parameters[$param->getName()] = $this->getMethodParameterConfig($param);
73
        }
74
75 7
        return $parameters;
76
    }
77
78 5
    private function getMethodParameterConfig(ReflectionParameter $param): ParameterConfig
79
    {
80 5
        return new ParameterConfig(
81 5
            type: $this->getMethodParameterTypeConfig($param),
82 5
            name: $param->getName(),
83 5
            allowsNull: $param->allowsNull(),
84 5
            isDefaultValueAvailable: $param->isDefaultValueAvailable(),
85 5
            isDefaultValueConstant: $param->isDefaultValueAvailable()
86 2
                ? $param->isDefaultValueConstant()
87 5
                : null,
88 5
            defaultValueConstantName: $param->isOptional()
89 2
                ? $param->getDefaultValueConstantName()
90 5
                : null,
91 5
            defaultValue: $param->isOptional()
92 2
                ? $param->getDefaultValue()
93 5
                : null,
94
        );
95
    }
96
97 5
    private function getMethodParameterTypeConfig(ReflectionParameter $param): ?TypeConfig
98
    {
99 5
        $type = $param->getType();
100 5
        if (!$type) {
101 2
            return null;
102
        }
103
104 5
        if ($type instanceof ReflectionUnionType) {
105 2
            $name = $this->getUnionType($type);
106
        } else {
107
            /** @var ReflectionNamedType $type */
108 5
            $name = $type->getName();
109
        }
110
111 5
        return new TypeConfig(
112
            name: $name,
113 5
            allowsNull: $type->allowsNull(),
114
        );
115
    }
116
117 7
    private function getMethodTypeConfig(ReflectionMethod $method): ?TypeConfig
118
    {
119 7
        $returnType = $method->getReturnType();
120 7
        if (!$returnType) {
121 2
            return null;
122
        }
123
124 7
        if ($returnType instanceof ReflectionUnionType) {
125 3
            $name = $this->getUnionType($returnType);
126
        } else {
127
            /** @var ReflectionNamedType $returnType */
128 7
            $name = $returnType->getName();
129
        }
130
131 7
        return new TypeConfig(
132
            name: $name,
133 7
            allowsNull: $returnType->allowsNull(),
134
        );
135
    }
136
137 5
    private function getUnionType(ReflectionUnionType $type): string
138
    {
139 5
        $types = array_map(
140 5
            static fn (ReflectionNamedType $namedType) => $namedType->getName(),
141 5
            $type->getTypes()
142
        );
143
144 5
        return implode('|', $types);
145
    }
146
}
147