Passed
Push — master ( 3a280d...539d3e )
by Alexander
02:49 queued 01:18
created

DefinitionExtractor::fromParameter()   B

Complexity

Conditions 10
Paths 15

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 10.1

Importance

Changes 0
Metric Value
eloc 9
dl 0
loc 18
ccs 9
cts 10
cp 0.9
rs 7.6666
c 0
b 0
f 0
cc 10
nc 15
nop 1
crap 10.1

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Factory\Extractors;
6
7
use Yiisoft\Factory\Definitions\DefinitionInterface;
8
use Yiisoft\Factory\Definitions\ClassDefinition;
9
use Yiisoft\Factory\Definitions\InvalidDefinition;
10
use Yiisoft\Factory\Definitions\ValueDefinition;
11
use Yiisoft\Factory\Exceptions\NotInstantiableException;
12
13
/**
14
 * Class DefinitionExtractor
15
 * This implementation resolves dependencies by using class type hints.
16
 * Note that service names need not match the parameter names, parameter names are ignored
17
 */
18
class DefinitionExtractor implements ExtractorInterface
19
{
20 13
    public function fromClassName(string $class): array
21
    {
22 13
        $reflectionClass = new \ReflectionClass($class);
23 13
        if (!$reflectionClass->isInstantiable()) {
24 5
            throw new NotInstantiableException($class);
25
        }
26 13
        $constructor = $reflectionClass->getConstructor();
27 13
        return $constructor === null ? [] : $this->fromFunction($constructor);
28
    }
29
30
    /**
31
     * @suppress PhanUndeclaredMethod
32
     */
33 11
    private function fromFunction(\ReflectionFunctionAbstract $reflectionFunction): array
34
    {
35 11
        $result = [];
36 11
        foreach ($reflectionFunction->getParameters() as $parameter) {
37 11
            $result[$parameter->getName()] = $this->fromParameter($parameter);
38
        }
39 11
        return $result;
40
    }
41
42
    /**
43
     * @suppress PhanUndeclaredMethod
44
     */
45 11
    private function fromParameter(\ReflectionParameter $parameter): DefinitionInterface
46
    {
47 11
        $type = $parameter->getType();
48 11
        $hasDefault = $parameter->isOptional() || $parameter->isDefaultValueAvailable() || (isset($type) && $type->allowsNull());
49
50 11
        if (!$hasDefault && $type === null) {
51
            return new InvalidDefinition();
52
        }
53
54
        // Our parameter has a class type hint
55 11
        if ($type !== null && !$type->isBuiltin()) {
56 8
            return new ClassDefinition($type->getName(), $type->allowsNull());
57
        }
58
59
        // Our parameter does not have a class type hint and either has a default value or is nullable.
60 4
        return new ValueDefinition(
61 4
            $parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() : null,
62 4
            $type !== null ? $type->getName() : null
63
        );
64
    }
65
66
    public function fromCallable(callable $callable): array
67
    {
68
        return $this->fromFunction(new \ReflectionFunction(\Closure::fromCallable($callable)));
69
    }
70
}
71