Passed
Pull Request — master (#8)
by Sergei
02:40
created

ParameterDefinition   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 91
Duplicated Lines 0 %

Test Coverage

Coverage 88.37%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 40
c 1
b 0
f 0
dl 0
loc 91
ccs 38
cts 43
cp 0.8837
rs 10
wmc 14

7 Methods

Rating   Name   Duplication   Size   Complexity  
A isVariadic() 0 3 1
A getCallable() 0 11 2
A isOptional() 0 3 1
A __construct() 0 3 1
A hasValue() 0 3 2
A getType() 0 22 3
A resolve() 0 28 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Definitions;
6
7
use ReflectionNamedType;
8
use ReflectionParameter;
9
use ReflectionUnionType;
10
use Yiisoft\Definitions\Contract\DefinitionInterface;
11
use Yiisoft\Definitions\Contract\DependencyResolverInterface;
12
use Yiisoft\Definitions\Exception\NotInstantiableException;
13
14
final class ParameterDefinition implements DefinitionInterface
15
{
16
    private ReflectionParameter $parameter;
17
18 18
    public function __construct(ReflectionParameter $parameter)
19
    {
20 18
        $this->parameter = $parameter;
21 18
    }
22
23 20
    public function isVariadic(): bool
24
    {
25 20
        return $this->parameter->isVariadic();
26
    }
27
28 20
    public function isOptional(): bool
29
    {
30 20
        return $this->parameter->isOptional();
31
    }
32
33 19
    public function hasValue(): bool
34
    {
35 19
        return $this->parameter->isDefaultValueAvailable() || $this->parameter->allowsNull();
36
    }
37
38 22
    public function resolve(DependencyResolverInterface $dependencyResolver)
39
    {
40 22
        if ($this->parameter->isDefaultValueAvailable()) {
41 18
            return $this->parameter->getDefaultValue();
42
        }
43
44 4
        if ($this->parameter->allowsNull()) {
45 1
            return null;
46
        }
47
48 3
        if ($this->isOptional()) {
49 2
            throw new NotInstantiableException(
50 2
                sprintf(
51
                    'Can not determine default value of parameter "%s" when instantiating "%s" ' .
52 2
                    'because it is PHP internal. Please specify argument explicitly.',
53 2
                    $this->parameter->getName(),
54 2
                    $this->getCallable(),
55
                )
56
            );
57
        }
58
59 1
        throw new NotInstantiableException(
60 1
            sprintf(
61
                'Can not determine value of the "%s" parameter of type "%s" when instantiating "%s". ' .
62 1
                'Please specify argument explicitly.',
63 1
                $this->parameter->getName(),
64 1
                $this->getType(),
65 1
                $this->getCallable(),
66
            )
67
        );
68
    }
69
70 1
    private function getType(): string
71
    {
72 1
        $type = $this->parameter->getType();
73
74 1
        if ($type === null) {
75
            return 'undefined';
76
        }
77
78
        /** @psalm-suppress UndefinedClass, TypeDoesNotContainType */
79 1
        if ($type instanceof ReflectionUnionType) {
80
            /** @var ReflectionNamedType[] */
81
            $namedTypes = $type->getTypes();
82
            $names = array_map(
83
                static fn (ReflectionNamedType $t) => $t->getName(),
84
                $namedTypes
85
            );
86
            return implode('|', $names);
87
        }
88
89
        /** @var ReflectionNamedType $type */
90
91 1
        return $type->getName();
92
    }
93
94 3
    private function getCallable(): string
95
    {
96 3
        $callable = [];
97
98 3
        $class = $this->parameter->getDeclaringClass();
99 3
        if ($class !== null) {
100 2
            $callable[] = $class->getName();
101
        }
102 3
        $callable[] = $this->parameter->getDeclaringFunction()->getName() . '()';
103
104 3
        return implode('::', $callable);
105
    }
106
}
107