Completed
Push — master ( d10f54...00ced4 )
by
unknown
05:32
created

DefinitionAnalyzer::analyzeParameter()   B

Complexity

Conditions 6
Paths 7

Size

Total Lines 27
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 6.0131

Importance

Changes 0
Metric Value
dl 0
loc 27
rs 8.439
c 0
b 0
f 0
ccs 13
cts 14
cp 0.9286
cc 6
eloc 18
nc 7
nop 3
crap 6.0131
1
<?php
0 ignored issues
show
Coding Style introduced by
End of line character is invalid; expected "\n" but found "\r\n"
Loading history...
2
/**
3
 * Created by Ruslan Molodyko.
4
 * Date: 10.09.2016
5
 * Time: 15:33
6
 */
7
namespace samsonframework\container\definition\analyzer;
8
9
use samsonframework\container\definition\analyzer\exception\ParameterNotFoundException;
10
use samsonframework\container\definition\builder\DefinitionBuilder;
11
use samsonframework\container\definition\analyzer\exception\WrongAnalyzerTypeException;
12
use samsonframework\container\definition\ClassDefinition;
13
use samsonframework\container\definition\MethodDefinition;
14
use samsonframework\container\definition\ParameterDefinition;
15
use samsonframework\container\tests\classes\annotation\PropClass;
16
17
/**
18
 * Class DefinitionAnalyzer
19
 * Fill metadata(definition)
20
 *
21
 * @author Ruslan Molodyko <[email protected]>
22
 */
23
class DefinitionAnalyzer
24
{
25
    /** ClassAnalyzerInterface[] */
26
    protected $classAnalyzers = [];
27
    /** MethodAnalyzerInterface[] */
28
    protected $methodAnalyzers = [];
29
    /** PropertyAnalyzerInterface[] */
30
    protected $propertyAnalyzers = [];
31
    /** ParameterAnalyzerInterface[] */
32
    protected $parameterAnalyzers = [];
33
34
    /**
35
     * DefinitionAnalyzer constructor.
36
     *
37
     * @param ClassAnalyzerInterface[] $classAnalyzers
38
     * @param MethodAnalyzerInterface[] $methodAnalyzers
39
     * @param PropertyAnalyzerInterface[] $propertyAnalyzers
40
     * @param ParameterAnalyzerInterface[] $parameterAnalyzers
41
     */
42 9
    public function __construct($classAnalyzers = [], $methodAnalyzers = [], $propertyAnalyzers = [], $parameterAnalyzers = []) {
43 9
        $this->classAnalyzers = $classAnalyzers;
44 9
        $this->methodAnalyzers = $methodAnalyzers;
45 9
        $this->propertyAnalyzers = $propertyAnalyzers;
46 9
        $this->parameterAnalyzers = $parameterAnalyzers;
47 9
    }
48
49
    /**
50
     * Analyze definition builder
51
     *
52
     * @param DefinitionBuilder $definitionBuilder
53
     * @throws ParameterNotFoundException
54
     * @throws WrongAnalyzerTypeException
55
     * @return bool
56
     */
57 7
    public function analyze(DefinitionBuilder $definitionBuilder): bool
58
    {
59 7
        $isAnalyzed = false;
60
        // Analyze class definitions
61 7
        foreach ($definitionBuilder->getDefinitionCollection() as $classDefinition) {
62
            // Analyze only not analyzed classes
63 7
            if (!$classDefinition->isAnalyzed()) {
64
                // Analyze class
65 7
                $this->analyzeClass($classDefinition);
66
                // Class was analyzed
67 6
                $classDefinition->setIsAnalyzed(true);
68 6
                $isAnalyzed = true;
69
            }
70
        }
71
72 6
        return $isAnalyzed;
73
    }
74
75
    /**
76
     * Analyze class
77
     *
78
     * @param ClassDefinition $classDefinition
79
     * @throws WrongAnalyzerTypeException
80
     * @throws ParameterNotFoundException
81
     */
82 7
    protected function analyzeClass(ClassDefinition $classDefinition)
83
    {
84
        // Get reflection
85 7
        $reflectionClass = new \ReflectionClass($classDefinition->getClassName());
86
87
        // Iterate analyzers
88 6
        foreach ($this->classAnalyzers as $classAnalyzer) {
89 6
            if ($classAnalyzer instanceof ClassAnalyzerInterface) {
90 6
                $classAnalyzer->analyze($this, $reflectionClass, $classDefinition);
91
            } else {
92
                throw new WrongAnalyzerTypeException(sprintf(
93 6
                    'Analyzer "%s" should implements ClassAnalyzerInterface',
94
                    get_class($classAnalyzer)
95
                ));
96
            }
97
        }
98
99
        // Analyze properties
100 6
        $this->analyzeProperty($reflectionClass, $classDefinition);
101
        // Analyze methods
102 6
        $this->analyzeMethod($reflectionClass, $classDefinition);
103 6
    }
104
105
    /**
106
     * Analyze method
107
     *
108
     * @param \ReflectionClass $reflectionClass
109
     * @param ClassDefinition $classDefinition
110
     * @throws ParameterNotFoundException
111
     * @throws WrongAnalyzerTypeException
112
     */
113 6
    protected function analyzeMethod(\ReflectionClass $reflectionClass, ClassDefinition $classDefinition)
114
    {
115
        // Analyze method definitions
116 6
        foreach ($reflectionClass->getMethods() as $reflectionMethod) {
117 6 View Code Duplication
            foreach ($this->methodAnalyzers as $methodAnalyzer) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
118 6
                if ($methodAnalyzer instanceof MethodAnalyzerInterface) {
119 6
                    $methodDefinition = $classDefinition->getMethodsCollection()[$reflectionMethod->getName()] ?? null;
0 ignored issues
show
Bug introduced by
Consider using $reflectionMethod->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
120 6
                    $methodAnalyzer->analyze($this, $reflectionMethod, $classDefinition, $methodDefinition);
121
                } else {
122
                    throw new WrongAnalyzerTypeException(sprintf(
123 6
                        'Analyzer "%s" should implements MethodAnalyzerInterface',
124
                        get_class($methodAnalyzer)
125
                    ));
126
                }
127
            }
128 6
            $methodDefinition = $classDefinition->getMethodsCollection()[$reflectionMethod->getName()] ?? null;
0 ignored issues
show
Bug introduced by
Consider using $reflectionMethod->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
129 6
            $this->analyzeParameter($reflectionMethod, $classDefinition, $methodDefinition);
130
        }
131 6
    }
132
133
    /**
134
     * Analyze property
135
     *
136
     * @param \ReflectionClass $reflectionClass
137
     * @param ClassDefinition $classDefinition
138
     * @throws WrongAnalyzerTypeException
139
     */
140 6
    protected function analyzeProperty(\ReflectionClass $reflectionClass, ClassDefinition $classDefinition)
141
    {
142
        // Iterate class properties
143 6 View Code Duplication
        foreach ($reflectionClass->getProperties() as $reflectionProperty) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
144
            // Analyze property definition
145 6
            foreach ($this->propertyAnalyzers as $propertyAnalyzer) {
146 6
                if ($propertyAnalyzer instanceof PropertyAnalyzerInterface) {
147 6
                    $propertyDefinition = $classDefinition->getPropertiesCollection()[$reflectionProperty->getName()] ?? null;
148 6
                    $propertyAnalyzer->analyze($this, $reflectionProperty, $classDefinition, $propertyDefinition);
149
                } else {
150
                    throw new WrongAnalyzerTypeException(sprintf(
151 6
                        'Analyzer "%s" should implements PropertyAnalyzerInterface',
152
                        get_class($propertyAnalyzer)
153
                    ));
154
                }
155
            }
156
        }
157 6
    }
158
159
    /**
160
     * Analyze parameter
161
     *
162
     * @param \ReflectionMethod $reflectionMethod
163
     * @param ClassDefinition $classDefinition
164
     * @param MethodDefinition $methodDefinition
165
     * @throws ParameterNotFoundException
166
     * @throws WrongAnalyzerTypeException
167
     */
168 6
    protected function analyzeParameter(
169
        \ReflectionMethod $reflectionMethod,
170
        ClassDefinition $classDefinition,
171
        MethodDefinition $methodDefinition = null
172
    ) {
173
        // Get methods parameters
174 6
        foreach ($reflectionMethod->getParameters() as $reflectionParameter) {
175 6
            $parameterDefinition = null;
0 ignored issues
show
Unused Code introduced by
$parameterDefinition is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
176 6
            $parameterName = $reflectionParameter->getName();
0 ignored issues
show
Bug introduced by
Consider using $reflectionParameter->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
177
            // Analyze parameters
178 6
            foreach ($this->parameterAnalyzers as $parameterAnalyzer) {
179 6
                if ($parameterAnalyzer instanceof ParameterAnalyzerInterface) {
180
                    /** @var ParameterDefinition $parameterDefinition */
181 6
                    $parameterDefinition = $methodDefinition &&
182 6
                    array_key_exists($parameterName, $methodDefinition->getParametersCollection())
183 6
                        ? $methodDefinition->getParametersCollection()[$parameterName]
184 6
                        : null;
185 6
                    $parameterAnalyzer->analyze($this, $reflectionParameter, $classDefinition, $methodDefinition, $parameterDefinition);
186
                } else {
187
                    throw new WrongAnalyzerTypeException(sprintf(
188 6
                        'Analyzer "%s" should implements ParameterAnalyzerInterface',
189
                        get_class($parameterAnalyzer)
190
                    ));
191
                }
192
            }
193
        }
194 6
    }
195
}
196