Test Failed
Pull Request — master (#870)
by Aleksei
08:56
created

ResolvingState::resolveParameterByNameOrPosition()   B

Complexity

Conditions 10
Paths 16

Size

Total Lines 31
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 20
dl 0
loc 31
rs 7.6666
c 0
b 0
f 0
cc 10
nc 16
nop 2

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spiral\Core\Internal\Resolver;
6
7
use ReflectionFunctionAbstract;
8
use ReflectionParameter;
9
use Spiral\Core\Exception\Resolver\ResolvingException;
10
11
/**
12
 * @internal
13
 */
14
final class ResolvingState
15
{
16
    public readonly bool $modeNamed;
17
18
    /**
19
     * @psalm-var array<array-key, mixed>
20
     */
21
    private array $resolvedValues = [];
22
23
    public function __construct(
24
        public readonly ReflectionFunctionAbstract $reflection,
25
        private array $arguments,
26
    ) {
27
        $this->modeNamed = $this->isNamedMode();
0 ignored issues
show
Bug introduced by
The property modeNamed is declared read-only in Spiral\Core\Internal\Resolver\ResolvingState.
Loading history...
28
    }
29
30
    public function addResolvedValue(mixed &$value, string $key = null): void
31
    {
32
        if ($key === null) {
33
            $this->resolvedValues[] = &$value;
34
        } else {
35
            $this->resolvedValues[$key] = &$value;
36
        }
37
    }
38
39
    public function resolveParameterByNameOrPosition(ReflectionParameter $parameter, bool $variadic): array
40
    {
41
        $key = $this->modeNamed
42
            ? $parameter->getName()
43
            : $parameter->getPosition();
44
45
        if (!\array_key_exists($key, $this->arguments)) {
46
            return [];
47
        }
48
        $_val = &$this->arguments[$key];
49
50
        if ($variadic && \is_array($_val)) {
51
            // Save keys is possible
52
            $positional = true;
53
            $result = [];
54
            foreach ($_val as $key => &$item) {
55
                if (!$positional && \is_int($key)) {
56
                    throw new ResolvingException(
57
                        'Cannot use positional argument after named argument during unpacking named variadic argument.'
58
                    );
59
                }
60
                $positional = $positional && \is_int($key);
61
                if ($positional) {
62
                    $result[] = &$item;
63
                } else {
64
                    $result[$key] = &$item;
65
                }
66
            }
67
            return $result;
68
        }
69
        return [&$_val];
70
    }
71
72
    public function getResolvedValues(): array
73
    {
74
        return $this->resolvedValues;
75
    }
76
77
    private function isNamedMode(): bool
78
    {
79
        $nums = 0;
80
        $strings = 0;
81
        foreach ($this->arguments as $key => $_) {
82
            if (\is_int($key)) {
83
                ++$nums;
84
            } else {
85
                ++$strings;
86
            }
87
        }
88
89
        return match (true) {
90
            $nums === 0 => true,
91
            $strings === 0 => false,
92
            default => throw new ResolvingException(
93
                'You can not use both numeric and string keys for predefined arguments.'
94
            )
95
        };
96
    }
97
}
98