Complex classes like ReflectionFileNamespace often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use ReflectionFileNamespace, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
27 | class ReflectionFileNamespace |
||
28 | { |
||
29 | /** |
||
30 | * List of classes in the namespace |
||
31 | * |
||
32 | * @var array|ReflectionClass[] |
||
33 | */ |
||
34 | protected $fileClasses; |
||
35 | |||
36 | /** |
||
37 | * List of functions in the namespace |
||
38 | * |
||
39 | * @var array|ReflectionFunction[] |
||
40 | */ |
||
41 | protected $fileFunctions; |
||
42 | |||
43 | /** |
||
44 | * List of constants in the namespace |
||
45 | * |
||
46 | * @var array |
||
47 | */ |
||
48 | protected $fileConstants; |
||
49 | |||
50 | /** |
||
51 | * List of constants in the namespace including defined via "define(...)" |
||
52 | * |
||
53 | * @var array |
||
54 | */ |
||
55 | protected $fileConstantsWithDefined; |
||
56 | |||
57 | /** |
||
58 | * List of imported namespaces (aliases) |
||
59 | * |
||
60 | * @var array |
||
61 | */ |
||
62 | protected $fileNamespaceAliases; |
||
63 | |||
64 | /** |
||
65 | * Namespace node |
||
66 | * |
||
67 | * @var Namespace_ |
||
68 | */ |
||
69 | private $namespaceNode; |
||
70 | |||
71 | /** |
||
72 | * Name of the file |
||
73 | * |
||
74 | * @var string |
||
75 | */ |
||
76 | private $fileName; |
||
77 | |||
78 | /** |
||
79 | * File namespace constructor |
||
80 | * |
||
81 | * @param string $fileName Name of the file |
||
82 | * @param string $namespaceName Name of the namespace |
||
83 | * @param Namespace_|null $namespaceNode Optional AST-node for this namespace block |
||
84 | */ |
||
85 | 3037 | public function __construct($fileName, $namespaceName, Namespace_ $namespaceNode = null) |
|
102 | |||
103 | /** |
||
104 | * Returns the concrete class from the file namespace or false if there is no class |
||
105 | * |
||
106 | * @param string $className |
||
107 | * |
||
108 | * @return bool|ReflectionClass |
||
109 | */ |
||
110 | 3001 | public function getClass($className) |
|
118 | |||
119 | /** |
||
120 | * Gets list of classes in the namespace |
||
121 | * |
||
122 | * @return ReflectionClass[]|array |
||
123 | */ |
||
124 | 3004 | public function getClasses() |
|
132 | |||
133 | /** |
||
134 | * Returns a value for the constant |
||
135 | * |
||
136 | * @param string $constantName name of the constant to fetch |
||
137 | * |
||
138 | * @return bool|mixed |
||
139 | */ |
||
140 | 14 | public function getConstant($constantName) |
|
148 | |||
149 | /** |
||
150 | * Returns a list of defined constants in the namespace |
||
151 | * |
||
152 | * @param bool $withDefined Include constants defined via "define(...)" in results. |
||
153 | * |
||
154 | * @return array |
||
155 | */ |
||
156 | 26 | public function getConstants($withDefined = false) |
|
172 | |||
173 | /** |
||
174 | * Gets doc comments from a class. |
||
175 | * |
||
176 | * @return string|false The doc comment if it exists, otherwise "false" |
||
177 | */ |
||
178 | 1 | public function getDocComment() |
|
189 | |||
190 | /** |
||
191 | * Gets starting line number |
||
192 | * |
||
193 | * @return integer |
||
194 | */ |
||
195 | 1 | public function getEndLine() |
|
199 | |||
200 | /** |
||
201 | * Returns the name of file |
||
202 | * |
||
203 | * @return string |
||
204 | */ |
||
205 | 5 | public function getFileName() |
|
209 | |||
210 | /** |
||
211 | * Returns the concrete function from the file namespace or false if there is no function |
||
212 | * |
||
213 | * @param string $functionName |
||
214 | * |
||
215 | * @return bool|ReflectionFunction |
||
216 | */ |
||
217 | 9 | public function getFunction($functionName) |
|
225 | |||
226 | /** |
||
227 | * Gets list of functions in the namespace |
||
228 | * |
||
229 | * @return ReflectionFunction[]|array |
||
230 | */ |
||
231 | 17 | public function getFunctions() |
|
239 | |||
240 | /** |
||
241 | * Gets namespace name |
||
242 | * |
||
243 | * @return string |
||
244 | */ |
||
245 | 3026 | public function getName() |
|
251 | |||
252 | /** |
||
253 | * Returns a list of namespace aliases |
||
254 | * |
||
255 | * @return array |
||
256 | */ |
||
257 | 1 | public function getNamespaceAliases() |
|
265 | |||
266 | /** |
||
267 | * Returns an AST-node for namespace |
||
268 | * |
||
269 | * @return Namespace_ |
||
270 | */ |
||
271 | public function getNode() |
||
275 | |||
276 | /** |
||
277 | * Helper method to access last token position for namespace |
||
278 | * |
||
279 | * This method is useful because namespace can be declared with braces or without them |
||
280 | */ |
||
281 | public function getLastTokenPosition() |
||
291 | |||
292 | /** |
||
293 | * Gets starting line number |
||
294 | * |
||
295 | * @return integer |
||
296 | */ |
||
297 | 1 | public function getStartLine() |
|
301 | |||
302 | /** |
||
303 | * Checks if the given class is present in this filenamespace |
||
304 | * |
||
305 | * @param string $className |
||
306 | * |
||
307 | * @return bool |
||
308 | */ |
||
309 | 3002 | public function hasClass($className) |
|
315 | |||
316 | /** |
||
317 | * Checks if the given constant is present in this filenamespace |
||
318 | * |
||
319 | * @param string $constantName |
||
320 | * |
||
321 | * @return bool |
||
322 | */ |
||
323 | 26 | public function hasConstant($constantName) |
|
329 | |||
330 | /** |
||
331 | * Checks if the given function is present in this filenamespace |
||
332 | * |
||
333 | * @param string $functionName |
||
334 | * |
||
335 | * @return bool |
||
336 | */ |
||
337 | 10 | public function hasFunction($functionName) |
|
343 | |||
344 | /** |
||
345 | * Searches for classes in the given AST |
||
346 | * |
||
347 | * @return array|ReflectionClass[] |
||
348 | */ |
||
349 | 3004 | private function findClasses() |
|
366 | |||
367 | /** |
||
368 | * Searches for functions in the given AST |
||
369 | * |
||
370 | * @return array |
||
371 | */ |
||
372 | 17 | private function findFunctions() |
|
390 | |||
391 | /** |
||
392 | * Searches for constants in the given AST |
||
393 | * |
||
394 | * @param bool $withDefined Include constants defined via "define(...)" in results. |
||
395 | * |
||
396 | * @return array |
||
397 | */ |
||
398 | 26 | private function findConstants($withDefined = false) |
|
438 | |||
439 | /** |
||
440 | * Searchse for namespace aliases for the current block |
||
441 | * |
||
442 | * @return array |
||
443 | */ |
||
444 | 1 | private function findNamespaceAliases() |
|
462 | } |
||
463 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.