Passed
Pull Request — 1.x (#321)
by Akihito
03:22 queued 57s
created

OptionsMethodRequest   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 141
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 42
dl 0
loc 141
rs 10
c 0
b 0
f 0
wmc 22

8 Methods

Rating   Name   Duplication   Size   Complexity  
A setParamMetas() 0 12 3
A getParameterType() 0 8 3
A getType() 0 10 2
A paramType() 0 8 2
A getParamMetas() 0 19 4
A paramDefault() 0 9 4
A getRequired() 0 12 3
A __invoke() 0 3 1
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
use function assert;
12
use function is_array;
13
use function is_string;
14
use function method_exists;
15
16
final class OptionsMethodRequest
17
{
18
    /**
19
     * Parameter #2 $paramMetas of method BEAR\Resource\OptionsMethodRequest::ignoreAnnotatedPrameter() expects array('parameters' => array<string, array('type' =>
20
     *
21
     * @param array<string, array{type: string, description?: string}> $paramDoc
22
     * @param array<string, string>                                    $ins
23
     *
24
     * @return array{parameters?: array<string, array{type?: string, description?: string, default?: string}>, required?: array<int, string>}
25
     */
26
    public function __invoke(ReflectionMethod $method, array $paramDoc, array $ins): array
27
    {
28
        return $this->getParamMetas($method->getParameters(), $paramDoc, $ins);
29
    }
30
31
    /**
32
     * @param array<string, array{type?: string, description?: string}> $paramDoc
33
     *
34
     * @psalm-suppress RedundantCondition for BC
35
     */
36
    private function getParameterType(ReflectionParameter $parameter, array $paramDoc, string $name): string|null
37
    {
38
        $hasType = method_exists($parameter, 'getType') && $parameter->getType();
39
        if ($hasType) {
40
            return $this->getType($parameter);
41
        }
42
43
        return $paramDoc[$name]['type'] ?? null;
44
    }
45
46
    /**
47
     * @param array<ReflectionParameter>                               $parameters
48
     * @param array<string, array{type: string, description?: string}> $paramDoc
49
     * @param array<string, string>                                    $ins
50
     *
51
     * @return array{parameters?: array<string, array{type?: string}>, required?: array<int, string>}
52
     */
53
    private function getParamMetas(array $parameters, array $paramDoc, array $ins): array
54
    {
55
        foreach ($parameters as $parameter) {
56
            $name = (string) $parameter->name;
57
            if (isset($ins[$name])) {
58
                $paramDoc[$name]['in'] = $ins[$parameter->name];
59
            }
60
61
            if (! isset($paramDoc[$parameter->name])) {
62
                $paramDoc[$name] = [];
63
            }
64
65
            $paramDoc = $this->paramType($paramDoc, $parameter);
66
            $paramDoc = $this->paramDefault($paramDoc, $parameter);
67
        }
68
69
        $required = $this->getRequired($parameters);
70
71
        return $this->setParamMetas($paramDoc, $required);
72
    }
73
74
    /**
75
     * @param array<ReflectionParameter> $parameters
76
     *
77
     * @return string[]
78
     * @psalm-return list<string>
79
     */
80
    private function getRequired(array $parameters): array
81
    {
82
        $required = [];
83
        foreach ($parameters as $parameter) {
84
            if ($parameter->isOptional()) {
85
                continue;
86
            }
87
88
            $required[] = $parameter->name;
89
        }
90
91
        return $required;
92
    }
93
94
    /**
95
     * @param array<string, array{type?: string, description?: string}> $paramDoc
96
     *
97
     * @return array<string, array{type?: string, description?: string, default?: string}>
98
     *
99
     * @throws ReflectionException
100
     */
101
    private function paramDefault(array $paramDoc, ReflectionParameter $parameter): array
102
    {
103
        $hasDefault = $parameter->isDefaultValueAvailable() && $parameter->getDefaultValue() !== null;
104
        if ($hasDefault) {
105
            $default = $parameter->getDefaultValue();
106
            $paramDoc[(string) $parameter->name]['default'] = is_array($default) ? '[]' : (string) $parameter->getDefaultValue(); // @phpstan-ignore-lines
107
        }
108
109
        return $paramDoc;
110
    }
111
112
    /**
113
     * @param array<string, array{type?: string, description?: string, default?: string, in?: string}> $paramDoc
114
     *
115
     * @return array<string, array{type?: string, description?: string, default?: string, in?: string}>
116
     */
117
    private function paramType(array $paramDoc, ReflectionParameter $parameter): array
118
    {
119
        $type = $this->getParameterType($parameter, $paramDoc, $parameter->name);
120
        if (is_string($type)) {
121
            $paramDoc[(string) $parameter->name]['type'] = $type; // override type parameter by reflection over phpdoc param type
122
        }
123
124
        return $paramDoc;
125
    }
126
127
    private function getType(ReflectionParameter $parameter): string
128
    {
129
        $namedType = $parameter->getType();
130
        assert($namedType instanceof ReflectionNamedType);
131
        $type = $namedType->getName();
132
        if ($type === 'int') {
133
            $type = 'integer';
134
        }
135
136
        return $type;
137
    }
138
139
    /**
140
     * @param array<string, array{type?: string}> $paramDoc
141
     * @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...
142
     *
143
     * @return array{parameters?: array<string, array{type?: string}>, required?: array<int, string>}
144
     */
145
    private function setParamMetas(array $paramDoc, array $required): array
146
    {
147
        $paramMetas = [];
148
        if ((bool) $paramDoc) {
149
            $paramMetas['parameters'] = $paramDoc;
150
        }
151
152
        if ((bool) $required) {
153
            $paramMetas['required'] = $required;
154
        }
155
156
        return $paramMetas;
157
    }
158
}
159