Reference::resolve()   A
last analyzed

Complexity

Conditions 6
Paths 6

Size

Total Lines 34
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 6

Importance

Changes 0
Metric Value
cc 6
eloc 17
nc 6
nop 2
dl 0
loc 34
ccs 16
cts 16
cp 1
crap 6
rs 9.0777
c 0
b 0
f 0
1
<?php
2
declare(strict_types = 1);
3
4
namespace Innmind\Compose\Definition\Service\Argument;
5
6
use Innmind\Compose\{
7
    Definition\Service\Argument,
8
    Definition\Service\Arguments,
9
    Definition\Name,
10
    Services,
11
    Lazy,
12
    Compilation\Service\Argument as CompiledArgument,
13
    Compilation\Service\Argument\Reference as CompiledReference,
14
    Exception\ValueNotSupported,
15
    Exception\ArgumentNotProvided,
16
    Exception\ArgumentNotDefined,
17
    Exception\ReferenceNotFound
18
};
19
use Innmind\Immutable\{
20
    StreamInterface,
21
    Str
22
};
23
24
final class Reference implements Argument, HoldReference
25
{
26
    private $name;
27
28 57
    public function __construct(Name $name)
29
    {
30 57
        $this->name = $name;
31 57
    }
32
33
    /**
34
     * {@inheritdoc}
35
     */
36 42
    public static function fromValue($value, Arguments $arguments): Argument
37
    {
38 42
        if (!is_string($value)) {
39 12
            throw new ValueNotSupported;
40
        }
41
42 38
        $value = Str::of($value);
43
44 38
        if ((string) $value->substring(0, 1) !== '$') {
45 17
            throw new ValueNotSupported((string) $value);
46
        }
47
48 30
        return new self(new Name(
49 30
            (string) $value->substring(1)
50
        ));
51
    }
52
53
    /**
54
     * {@inheritdoc}
55
     */
56 23
    public function resolve(
57
        StreamInterface $built,
58
        Services $services
59
    ): StreamInterface {
60
        try {
61 23
            return $built->add(
62 23
                $services->arguments()->get($this->name)
63
            );
64 21
        } catch (ArgumentNotProvided $e) {
65 8
            if ($e->argument()->hasDefault()) {
66 4
                return $built->add(Lazy::service(
67 4
                    $e->argument()->default(),
68 4
                    $services
69
                ));
70
            }
71
72 6
            if ($e->argument()->optional()) {
73 3
                return $built->add(null);
74
            }
75
76 3
            throw $e;
77 16
        } catch (ArgumentNotDefined $e) {
78
            //pass
79
        }
80
81
        try {
82 16
            return $built->add(
83 16
                $services->dependencies()->lazy($this->name)
84
            );
85 14
        } catch (ReferenceNotFound $e) {
86
            //pass
87
        }
88
89 14
        return $built->add(Lazy::service($this->name, $services));
90
    }
91
92 3
    public function reference(): Name
93
    {
94 3
        return $this->name;
95
    }
96
97 6
    public function compile(): CompiledArgument
98
    {
99 6
        return new CompiledReference($this->name);
100
    }
101
}
102