Arguments   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 63
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 10
eloc 21
c 0
b 0
f 0
dl 0
loc 63
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 2
A inject() 0 9 2
A bindInjectionPoint() 0 8 2
A getParameter() 0 11 3
A accept() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Ray\Di;
6
7
use Ray\Di\Exception\Unbound;
8
use ReflectionMethod;
9
10
final class Arguments implements AcceptInterface
11
{
12
    /** @var Argument[] */
13
    private $arguments = [];
14
15
    public function __construct(ReflectionMethod $method, Name $name)
16
    {
17
        $parameters = $method->getParameters();
18
        foreach ($parameters as $parameter) {
19
            $this->arguments[] = new Argument($parameter, $name($parameter));
20
        }
21
    }
22
23
    /**
24
     * Return arguments
25
     *
26
     * @return array<int, mixed>
27
     *
28
     * @throws Exception\Unbound
29
     */
30
    public function inject(Container $container): array
31
    {
32
        $parameters = [];
33
        foreach ($this->arguments as $parameter) {
34
            /** @psalm-suppress MixedAssignment */
35
            $parameters[] = $this->getParameter($container, $parameter);
36
        }
37
38
        return $parameters;
39
    }
40
41
    public function accept(VisitorInterface $visitor)
42
    {
43
        $visitor->visitArguments($this->arguments);
44
    }
45
46
    /**
47
     * @return mixed
48
     *
49
     * @throws Unbound
50
     */
51
    private function getParameter(Container $container, Argument $argument)
52
    {
53
        $this->bindInjectionPoint($container, $argument);
54
        try {
55
            return $container->getDependency((string) $argument);
56
        } catch (Unbound $e) {
57
            if ($argument->isDefaultAvailable()) {
58
                return $argument->getDefaultValue();
59
            }
60
61
            throw new Unbound($argument->getMeta(), 0, $e);
62
        }
63
    }
64
65
    private function bindInjectionPoint(Container $container, Argument $argument): void
66
    {
67
        $isSelf = (string) $argument === InjectionPointInterface::class . '-' . Name::ANY;
68
        if ($isSelf) {
69
            return;
70
        }
71
72
        (new Bind($container, InjectionPointInterface::class))->toInstance(new InjectionPoint($argument->get()));
73
    }
74
}
75