Passed
Pull Request — master (#17)
by Dmitriy
02:52
created

DefinitionExtractor   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 75
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 23
c 2
b 0
f 0
dl 0
loc 75
ccs 25
cts 25
cp 1
rs 10
wmc 11

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 2 1
A getInstance() 0 7 2
A fromFunction() 0 7 2
A fromClassName() 0 21 5
A fromParameter() 0 3 1
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 ReflectionNamedType;
11
use ReflectionParameter;
12
use ReflectionUnionType;
13
use Yiisoft\Definitions\ClassDefinition;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Definitions\ClassDefinition was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
use Yiisoft\Definitions\Contract\DefinitionInterface;
15
use Yiisoft\Definitions\Exception\NotFoundException;
16
use Yiisoft\Definitions\Exception\NotInstantiableClassException;
17
use Yiisoft\Definitions\Exception\NotInstantiableException;
18
use Yiisoft\Definitions\ParameterDefinition;
19
20
/**
21
 * This class resolves dependencies by using class type hints.
22
 * Note that service names need not match the parameter names, parameter names are ignored
23
 *
24
 * @internal
25
 */
26
final class DefinitionExtractor
27
{
28
    private static ?self $instance = null;
29
30
    /**
31
     * @psalm-var array<string, array<string, DefinitionInterface>>
32
     */
33
    private static array $dependencies = [];
34
35 1
    private function __construct()
36
    {
37 1
    }
38
39
    /**
40
     * Get an instance of this class or create it.
41
     *
42
     * @return static An instance of this class.
43
     */
44 35
    public static function getInstance(): self
45
    {
46 35
        if (self::$instance === null) {
47 1
            self::$instance = new self();
48
        }
49
50 35
        return self::$instance;
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::instance could return the type null which is incompatible with the type-hinted return Yiisoft\Definitions\Infr...ure\DefinitionExtractor. Consider adding an additional type-check to rule them out.
Loading history...
51
    }
52
53
    /**
54
     * @psalm-param class-string $class
55
     *
56
     * @throws NotFoundException
57
     * @throws NotInstantiableException
58
     *
59
     * @return DefinitionInterface[]
60
     * @psalm-return array<string, DefinitionInterface>
61
     */
62 31
    public function fromClassName(string $class): array
63
    {
64 31
        if (isset(self::$dependencies[$class])) {
65 17
            return self::$dependencies[$class];
66
        }
67
68
        try {
69 14
            $reflectionClass = new ReflectionClass($class);
70 1
        } catch (ReflectionException $e) {
71 1
            throw new NotFoundException($class);
72
        }
73
74 13
        if (!$reflectionClass->isInstantiable()) {
75 1
            throw new NotInstantiableClassException($class);
76
        }
77
78 12
        $constructor = $reflectionClass->getConstructor();
79 12
        $dependencies = $constructor === null ? [] : $this->fromFunction($constructor);
80 12
        self::$dependencies[$class] = $dependencies;
81
82 12
        return $dependencies;
83
    }
84
85
    /**
86
     * @return DefinitionInterface[]
87
     * @psalm-return array<string, DefinitionInterface>
88
     */
89 16
    public function fromFunction(ReflectionFunctionAbstract $reflectionFunction): array
90
    {
91 16
        $result = [];
92 16
        foreach ($reflectionFunction->getParameters() as $parameter) {
93 16
            $result[$parameter->getName()] = $this->fromParameter($parameter);
94
        }
95 16
        return $result;
96
    }
97
98 16
    private function fromParameter(ReflectionParameter $parameter): DefinitionInterface
99
    {
100 16
        return new ParameterDefinition($parameter);
101
    }
102
}
103