ExtensionDefinition::buildExtensionCode()   B
last analyzed

Complexity

Conditions 11
Paths 80

Size

Total Lines 59
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 39
nc 80
nop 1
dl 0
loc 59
rs 7.3166
c 0
b 0
f 0

How to fix   Long Method    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
4
namespace TheCodingMachine\Funky;
5
6
use ReflectionMethod;
7
use TheCodingMachine\Funky\Annotations\Extension;
8
use TheCodingMachine\Funky\Injections\Injection;
9
10
class ExtensionDefinition extends AbstractDefinition
11
{
12
    public function __construct(ReflectionMethod $reflectionMethod, Extension $annotation)
13
    {
14
        if (!$reflectionMethod->isPublic()) {
15
            throw BadModifierException::mustBePublic($reflectionMethod, '@Extension');
16
        }
17
        if (!$reflectionMethod->isStatic()) {
18
            throw BadModifierException::mustBeStatic($reflectionMethod, '@Extension');
19
        }
20
21
        if ($annotation->isFromMethodName()) {
22
            $this->name = $reflectionMethod->getName();
23
        } elseif ($annotation->isFromType()) {
24
            $returnType = $reflectionMethod->getReturnType();
25
            if ($returnType === null) {
26
                throw UnknownTypeException::create($reflectionMethod);
27
            }
28
            $this->name = (string) $returnType;
29
        } else {
30
            $this->name = (string) $annotation->getName();
31
        }
32
33
        $this->tags = $annotation->getTags();
34
35
        parent::__construct($reflectionMethod);
36
    }
37
38
    public function buildExtensionCode(string $functionName) : string
39
    {
40
        $returnTypeCode = '';
41
        $returnType = $this->reflectionMethod->getReturnType();
42
        if ($returnType) {
43
            $allowsNull = $returnType->allowsNull() ? '?':'';
44
            if ($returnType->isBuiltin()) {
45
                $returnTypeCode = ': '.$allowsNull.$returnType;
46
            } else {
47
                $returnTypeCode = ': '.$allowsNull.'\\'.$returnType;
48
            }
49
        }
50
51
        $parameters = $this->reflectionMethod->getParameters();
52
53
        $previousParameterCode = '';
54
        $previousTypeCode = '';
55
        if (count($parameters) >= 1) {
56
            $previousParameter = $this->reflectionMethod->getParameters()[0];
57
            $previousType = $previousParameter->getType();
58
            if ($previousType) {
59
                if ($previousType->isBuiltin()) {
60
                    $previousTypeCode = (string) $previousType.' ';
61
                } else {
62
                    $previousTypeCode = '\\'.(string) $previousType.' ';
63
                }
64
                if ($previousParameter->allowsNull()) {
65
                    $previousTypeCode = '?'.$previousTypeCode;
66
                }
67
            }
68
            $previousParameterCode = ', '.$previousTypeCode.'$previous';
69
            if ($previousParameter->isDefaultValueAvailable()) {
70
                $previousParameterCode .= ' = '.var_export($previousParameter->getDefaultValue(), true);
71
            } elseif ($previousParameter->allowsNull()) {
72
                // If a first argument has no default null value but is nullable (because of ?),
73
                // we still put the null default value.
74
                $previousParameterCode .= ' = null';
75
            }
76
        }
77
78
79
        return sprintf(
80
            <<<EOF
81
    public static function %s(ContainerInterface \$container%s)%s
82
    {
83
        return %s::%s(%s%s);
84
    }
85
    
86
EOF
87
            ,
88
            $functionName,
89
            $previousParameterCode,
90
            $returnTypeCode,
91
            '\\'.$this->reflectionMethod->getDeclaringClass()->getName(),
92
            $this->reflectionMethod->getName(),
93
            $previousParameterCode ? '$previous': '',
94
            implode('', array_map(function (Injection $injection) {
95
                return ', '.$injection->getCode();
96
            }, $this->getInjections()))
97
        );
98
    }
99
100
    /**
101
     * Returns a list of services to be injected.
102
     *
103
     * @return Injection[]
104
     */
105
    private function getInjections(): array
106
    {
107
        $parameters = $this->getReflectionMethod()->getParameters();
108
        array_shift($parameters);
109
        return array_map([$this, 'mapParameterToInjection'], $parameters);
110
    }
111
}
112