Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
1 | <?php |
||
43 | class Generator |
||
44 | { |
||
45 | |||
46 | /** |
||
47 | * The register for any known aspects |
||
48 | * |
||
49 | * @var \AppserverIo\Doppelgaenger\AspectRegister $aspectRegister |
||
50 | */ |
||
51 | protected $aspectRegister; |
||
52 | |||
53 | /** |
||
54 | * A cacheMap instance to organize our cache |
||
55 | * |
||
56 | * @var \AppserverIo\Doppelgaenger\CacheMap $cacheMap |
||
57 | */ |
||
58 | protected $cacheMap; |
||
59 | |||
60 | /** |
||
61 | * A structureMap instance to organize the known structures |
||
62 | * |
||
63 | * @var \AppserverIo\Doppelgaenger\StructureMap $structureMap |
||
64 | */ |
||
65 | protected $structureMap; |
||
66 | |||
67 | /** |
||
68 | * The aspect of the configuration we need |
||
69 | * |
||
70 | * @var \AppserverIo\Doppelgaenger\Config $config |
||
71 | */ |
||
72 | protected $config; |
||
73 | |||
74 | /** |
||
75 | * Collection of definitions and their inheritance relation to each other |
||
76 | * |
||
77 | * @var \AppserverIo\Doppelgaenger\Entities\Definitions\StructureDefinitionHierarchy $structureDefinitionHierarchy |
||
78 | */ |
||
79 | protected $structureDefinitionHierarchy; |
||
80 | |||
81 | /** |
||
82 | * Default constructor |
||
83 | * |
||
84 | * @param \AppserverIo\Doppelgaenger\StructureMap $structureMap A structureMap instance to organize the known structures |
||
85 | * @param \AppserverIo\Doppelgaenger\CacheMap $cacheMap A cacheMap instance to organize our cache |
||
86 | * @param \AppserverIo\Doppelgaenger\Config $config Configuration |
||
87 | * @param \AppserverIo\Doppelgaenger\AspectRegister $aspectRegister The register for known aspects |
||
88 | */ |
||
89 | public function __construct(StructureMap $structureMap, CacheMap $cacheMap, Config $config, AspectRegister $aspectRegister) |
||
97 | |||
98 | /** |
||
99 | * Will create an altered definition of the structure defined in the $mapEntry variable. |
||
100 | * Will also add it to the cache map |
||
101 | * |
||
102 | * @param \AppserverIo\Doppelgaenger\Entities\Definitions\Structure $mapEntry Entry of a StructureMap we want created |
||
103 | * @param boolean $createRecursive If contract inheritance is enabled |
||
104 | * |
||
105 | * @throws \AppserverIo\Doppelgaenger\Exceptions\GeneratorException |
||
106 | * |
||
107 | * @return boolean |
||
108 | */ |
||
109 | public function create(Structure $mapEntry, $createRecursive = false) |
||
154 | |||
155 | /** |
||
156 | * Will return the path the cached and altered definition will have |
||
157 | * |
||
158 | * @param string $structureName Name of the structure we want to update |
||
159 | * |
||
160 | * @return string |
||
161 | * |
||
162 | * TODO implement this somewhere more accessible, others might need it too (e.g. autoloader) |
||
163 | */ |
||
164 | protected function createFilePath($structureName) |
||
171 | |||
172 | /** |
||
173 | * Will create a file containing the altered definition |
||
174 | * |
||
175 | * @param string $targetFileName The intended name of the |
||
176 | * new file |
||
177 | * @param \AppserverIo\Doppelgaenger\Interfaces\StructureDefinitionInterface $structureDefinition The definition of the |
||
178 | * structure we will alter |
||
179 | * |
||
180 | * @throws \InvalidArgumentException |
||
181 | * |
||
182 | * @return boolean |
||
183 | */ |
||
184 | protected function createFileFromDefinition( |
||
203 | |||
204 | /** |
||
205 | * Will create a file with the altered class definition as its content. |
||
206 | * We will register the aspect first |
||
207 | * |
||
208 | * @param string $targetFileName The intended name of the new file |
||
209 | * @param \AppserverIo\Doppelgaenger\Entities\Definitions\AspectDefinition $aspectDefinition The definition of the structure we will alter |
||
210 | * |
||
211 | * @return boolean |
||
212 | */ |
||
213 | protected function createFileFromAspectDefinition($targetFileName, AspectDefinition $aspectDefinition) |
||
222 | |||
223 | /** |
||
224 | * Will create a file for a given interface definition. |
||
225 | * We will just copy the file here until the autoloader got refactored. |
||
226 | * |
||
227 | * @param string $targetFileName The intended name of the new file |
||
228 | * @param \AppserverIo\Doppelgaenger\Entities\Definitions\InterfaceDefinition $structureDefinition The definition of the structure we will alter |
||
229 | * |
||
230 | * @return boolean |
||
231 | * |
||
232 | * TODO remove when autoloader is able to recognize and skip interfaces |
||
233 | */ |
||
234 | protected function createFileFromInterfaceDefinition( |
||
253 | |||
254 | /** |
||
255 | * Will create a file with the altered class definition as its content |
||
256 | * |
||
257 | * @param string $targetFileName The intended name of the new file |
||
258 | * @param \AppserverIo\Doppelgaenger\Entities\Definitions\AbstractStructureDefinition $structureDefinition The definition of the structure we will alter |
||
259 | * |
||
260 | * @return boolean |
||
261 | */ |
||
262 | protected function createFileFromArbitraryDefinition( |
||
300 | |||
301 | /** |
||
302 | * Will append all needed filters based on the enforcement level stated in the configuration file. |
||
303 | * |
||
304 | * @param resource $res The resource we will append the filters to |
||
305 | * @param \AppserverIo\Doppelgaenger\Interfaces\StructureDefinitionInterface $structureDefinition Structure definition providing needed information |
||
306 | * |
||
307 | * @return array |
||
308 | */ |
||
309 | protected function appendDefaultFilters( |
||
420 | |||
421 | /** |
||
422 | * Will append a given filter to a resource. |
||
423 | * Might fail if the filter cannot be found. |
||
424 | * Will return true if filter got appended successfully |
||
425 | * |
||
426 | * @param resource $res The resource we will append the filters to |
||
427 | * @param string $filterClass The fully qualified name of the filter class |
||
428 | * @param mixed $params Whatever params the filter might need |
||
429 | * |
||
430 | * @return resource |
||
431 | * |
||
432 | * @throws \AppserverIo\Doppelgaenger\Exceptions\GeneratorException |
||
433 | */ |
||
434 | public function appendFilter(& $res, $filterClass, $params) |
||
451 | |||
452 | /** |
||
453 | * Return the cache path (as organized by our cache map) for a given structure name |
||
454 | * |
||
455 | * @param string $structureName The structure we want the cache path for |
||
456 | * |
||
457 | * @return boolean|string |
||
458 | */ |
||
459 | public function getFileName($structureName) |
||
470 | |||
471 | /** |
||
472 | * Method used to update certain structures |
||
473 | * |
||
474 | * @param string $structureName Name of the structure we want to update |
||
475 | * |
||
476 | * @return boolean |
||
477 | */ |
||
478 | public function update($structureName) |
||
482 | } |
||
483 |
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.