Passed
Push — master ( afe907...8afadc )
by Alexander
02:07
created

DefinitionExtractor   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 57
Duplicated Lines 0 %

Test Coverage

Coverage 89.47%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 18
c 2
b 0
f 0
dl 0
loc 57
ccs 17
cts 19
cp 0.8947
rs 10
wmc 8

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 2 1
A fromFunction() 0 7 2
A fromClassName() 0 21 5
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Definitions\Infrastructure;
6
7
use ReflectionClass;
8
use ReflectionException;
9
use ReflectionFunctionAbstract;
10
use Yiisoft\Definitions\Exception\NotInstantiableClassException;
11
use Yiisoft\Definitions\Exception\NotInstantiableException;
12
use Yiisoft\Definitions\ParameterDefinition;
13
14
/**
15
 * This class extracts dependency definitions from type hints of a function or a class constructor parameters.
16
 * Note that service names need not match the parameter names, parameter names are ignored.
17
 *
18
 * @internal
19
 */
20
final class DefinitionExtractor
21
{
22
    /**
23
     * @psalm-var array<string, array<string, ParameterDefinition>>
24
     */
25
    private static array $dependencies = [];
26
27
    private function __construct()
28
    {
29
    }
30
31
    /**
32
     * Extract dependency definitions from type hints of a class constructor parameters.
33
     *
34
     * @psalm-param class-string $class
35
     *
36
     * @throws NotInstantiableException
37
     *
38
     * @return ParameterDefinition[]
39
     * @psalm-return array<string, ParameterDefinition>
40
     */
41 36
    public static function fromClassName(string $class): array
42
    {
43 36
        if (isset(self::$dependencies[$class])) {
44 18
            return self::$dependencies[$class];
45
        }
46
47
        try {
48 18
            $reflectionClass = new ReflectionClass($class);
49 1
        } catch (ReflectionException $e) {
50 1
            throw new NotInstantiableClassException($class);
51
        }
52
53 17
        if (!$reflectionClass->isInstantiable()) {
54 3
            throw new NotInstantiableClassException($class);
55
        }
56
57 15
        $constructor = $reflectionClass->getConstructor();
58 15
        $dependencies = $constructor === null ? [] : self::fromFunction($constructor);
59 15
        self::$dependencies[$class] = $dependencies;
60
61 15
        return $dependencies;
62
    }
63
64
    /**
65
     * Extract dependency definitions from type hints of a function.
66
     *
67
     * @return ParameterDefinition[]
68
     * @psalm-return array<string, ParameterDefinition>
69
     */
70 19
    public static function fromFunction(ReflectionFunctionAbstract $reflectionFunction): array
71
    {
72 19
        $result = [];
73 19
        foreach ($reflectionFunction->getParameters() as $parameter) {
74 19
            $result[$parameter->getName()] = new ParameterDefinition($parameter);
75
        }
76 19
        return $result;
77
    }
78
}
79