Completed
Push — to_constructor_name ( ad781c...1a2acb )
by Akihito
09:40
created

Arguments::getDefaultValue()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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