Passed
Push — master ( 010398...c79e42 )
by Evgeniy
54s queued 12s
created

Reflection::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Cekta\DI;
6
7
use ReflectionClass;
8
use ReflectionException;
9
use ReflectionMethod;
10
11
class Reflection
12
{
13
    /**
14
     * @var ReflectionTransformer[]
15
     */
16
    private $transformers;
17
18 27
    public function __construct(ReflectionTransformer ...$tranfromers)
19
    {
20 27
        $this->transformers = $tranfromers;
21 27
    }
22
23
    /**
24
     * @param string $name
25
     * @return string[]
26
     * @internal
27
     */
28 18
    public function getDependencies(string $name): array
29
    {
30
        try {
31 18
            $class = new ReflectionClass($name);
32 15
            $dependencies = self::getMethodDependencies($class->getConstructor());
33 15
            return $this->tranform($class->getName(), $dependencies);
34 3
        } catch (ReflectionException $exception) {
35 3
            return [];
36
        }
37
    }
38
39
    /**
40
     * @param string $name
41
     * @return bool
42
     * @internal
43
     */
44 9
    public function isVariadic(string $name): bool
45
    {
46
        try {
47 9
            $class = new ReflectionClass($name);
48 6
            if ($class->getConstructor() !== null) {
49 6
                $parameters = $class->getConstructor()->getParameters();
50 6
                $count = count($parameters);
51 6
                return $count > 0 ? $parameters[$count - 1]->isVariadic() : false;
52
            }
53 3
            return false;
54 3
        } catch (ReflectionException $exception) {
55 3
            return false;
56
        }
57
    }
58
59
    /**
60
     * @param string $name
61
     * @return bool
62
     * @internal
63
     */
64 6
    public function isInstantiable(string $name): bool
65
    {
66
        try {
67 6
            $class = new ReflectionClass($name);
68 3
            return $class->isInstantiable();
69 3
        } catch (ReflectionException $exception) {
70 3
            return false;
71
        }
72
    }
73
74 15
    private static function getMethodDependencies(?ReflectionMethod $method): array
75
    {
76 15
        $parameters = [];
77 15
        if ($method !== null) {
78 12
            $annotations = self::getAnnotationParameters((string) $method->getDocComment());
79 12
            foreach ($method->getParameters() as $parameter) {
80 12
                $class = $parameter->getClass();
81 12
                $name = $class && $parameter->isVariadic() !== true ? $class->name : $parameter->name;
82 12
                $parameters[$name] = array_key_exists($name, $annotations) ? $annotations[$name] : $name;
83
            }
84
        }
85 15
        return array_values($parameters);
86
    }
87
88 15
    private function tranform(string $name, array $params)
89
    {
90 15
        foreach ($this->transformers as $tranfromer) {
91 3
            $params = $tranfromer->transform($name, $params);
92
        }
93 15
        return $params;
94
    }
95
96 12
    private static function getAnnotationParameters(string $comment)
97
    {
98 12
        $result = [];
99 12
        $matches = [];
100 12
        preg_match_all("/@inject \\\\?([\w\d\\\\]*) \\$([\w\d]*)/", $comment, $matches, PREG_SET_ORDER);
101 12
        foreach ($matches as $match) {
102 3
            $result[$match[2]] = $match[1];
103
        }
104 12
        return $result;
105
    }
106
}
107