Passed
Pull Request — 1.x (#321)
by Akihito
02:33
created

OptionsMethodRequest::getType()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 1
dl 0
loc 10
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BEAR\Resource\Options;
6
7
use ReflectionException;
8
use ReflectionMethod;
9
use ReflectionNamedType;
10
use ReflectionParameter;
11
12
use function assert;
13
use function is_array;
14
use function is_string;
15
use function method_exists;
16
17
final class OptionsMethodRequest
18
{
19
    /**
20
     * Parameter #2 $paramMetas of method BEAR\Resource\OptionsMethodRequest::ignoreAnnotatedPrameter() expects array('parameters' => array<string, array('type' =>
21
     *
22
     * @param array<string, array{type: string, description?: string}> $paramDoc
23
     * @param array<string, string>                                    $ins
24
     *
25
     * @return array{parameters?: array<string, array{type?: string, description?: string, default?: string}>, required?: array<int, string>}
26
     */
27
    public function __invoke(ReflectionMethod $method, array $paramDoc, array $ins): array
28
    {
29
        return $this->getParamMetas($method->getParameters(), $paramDoc, $ins);
30
    }
31
32
    /**
33
     * @param array<string, array{type?: string, description?: string}> $paramDoc
34
     *
35
     * @psalm-suppress RedundantCondition for BC
36
     */
37
    private function getParameterType(ReflectionParameter $parameter, array $paramDoc, string $name): string|null
38
    {
39
        $hasType = method_exists($parameter, 'getType') && $parameter->getType();
40
        if ($hasType) {
41
            return $this->getType($parameter);
42
        }
43
44
        return $paramDoc[$name]['type'] ?? null;
45
    }
46
47
    /**
48
     * @param array<ReflectionParameter>                               $parameters
49
     * @param array<string, array{type: string, description?: string}> $paramDoc
50
     * @param array<string, string>                                    $ins
51
     *
52
     * @return array{parameters?: array<string, array{type?: string}>, required?: array<int, string>}
53
     */
54
    private function getParamMetas(array $parameters, array $paramDoc, array $ins): array
55
    {
56
        foreach ($parameters as $parameter) {
57
            $name = $parameter->name;
58
            if (isset($ins[$name])) {
59
                $paramDoc[$name]['in'] = $ins[$parameter->name];
60
            }
61
62
            if (! isset($paramDoc[$parameter->name])) {
63
                $paramDoc[$name] = [];
64
            }
65
66
            $paramDoc = $this->paramType($paramDoc, $parameter);
67
            $paramDoc = $this->paramDefault($paramDoc, $parameter);
68
        }
69
70
        $required = $this->getRequired($parameters);
71
72
        return $this->setParamMetas($paramDoc, $required);
73
    }
74
75
    /**
76
     * @param array<ReflectionParameter> $parameters
77
     *
78
     * @return string[]
79
     * @psalm-return list<string>
80
     */
81
    private function getRequired(array $parameters): array
82
    {
83
        $required = [];
84
        foreach ($parameters as $parameter) {
85
            if ($parameter->isOptional()) {
86
                continue;
87
            }
88
89
            $required[] = $parameter->name;
90
        }
91
92
        return $required;
93
    }
94
95
    /**
96
     * @param array<string, array{type?: string, description?: string}> $paramDoc
97
     *
98
     * @return array<string, array{type?: string, description?: string, default?: string}>
99
     *
100
     * @throws ReflectionException
101
     */
102
    private function paramDefault(array $paramDoc, ReflectionParameter $parameter): array
103
    {
104
        $hasDefault = $parameter->isDefaultValueAvailable() && $parameter->getDefaultValue() !== null;
105
        if ($hasDefault) {
106
            /** @psalm-suppress MixedAssignment */
107
            $default = $parameter->getDefaultValue();
108
            $paramDoc[$parameter->name]['default'] = is_array($default) ? '[]' : (string) $parameter->getDefaultValue(); // @phpstan-ignore-lines
109
        }
110
111
        return $paramDoc;
112
    }
113
114
    /**
115
     * @param array<string, array{type?: string, description?: string, default?: string, in?: string}> $paramDoc
116
     *
117
     * @return array<string, array{type?: string, description?: string, default?: string, in?: string}>
118
     */
119
    private function paramType(array $paramDoc, ReflectionParameter $parameter): array
120
    {
121
        $type = $this->getParameterType($parameter, $paramDoc, $parameter->name);
122
        if (is_string($type)) {
123
            $paramDoc[$parameter->name]['type'] = $type; // override type parameter by reflection over phpdoc param type
124
        }
125
126
        return $paramDoc;
127
    }
128
129
    private function getType(ReflectionParameter $parameter): string
130
    {
131
        $namedType = $parameter->getType();
132
        assert($namedType instanceof ReflectionNamedType);
133
        $type = $namedType->getName();
134
        if ($type === 'int') {
135
            $type = 'integer';
136
        }
137
138
        return $type;
139
    }
140
141
    /**
142
     * @param array<string, array{type?: string}> $paramDoc
143
     * @param list<string>                        $required
0 ignored issues
show
Bug introduced by
The type BEAR\Resource\Options\list was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
144
     *
145
     * @return array{parameters?: array<string, array{type?: string}>, required?: array<int, string>}
146
     */
147
    private function setParamMetas(array $paramDoc, array $required): array
148
    {
149
        $paramMetas = [];
150
        if ((bool) $paramDoc) {
151
            $paramMetas['parameters'] = $paramDoc;
152
        }
153
154
        if ((bool) $required) {
155
            $paramMetas['required'] = $required;
156
        }
157
158
        return $paramMetas;
159
    }
160
}
161