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 |
||
16 | class DocSummaryHelper |
||
17 | { |
||
18 | /** |
||
19 | * The php cs file. |
||
20 | * |
||
21 | * @var File |
||
22 | */ |
||
23 | private $file; |
||
24 | |||
25 | /** |
||
26 | * The doc comment helper. |
||
27 | * |
||
28 | * @var DocHelper |
||
29 | */ |
||
30 | private $docHelper; |
||
31 | |||
32 | /** |
||
33 | * Token stack of the current file. |
||
34 | * |
||
35 | * @var array |
||
36 | */ |
||
37 | private $tokens; |
||
38 | |||
39 | /** |
||
40 | * DocSummaryHelper constructor. |
||
41 | * |
||
42 | * @param File $file The php cs file |
||
43 | * @param DocHelper $docHelper The doc comment helper |
||
44 | */ |
||
45 | 121 | public function __construct(File $file, DocHelper $docHelper) |
|
51 | |||
52 | /** |
||
53 | * Returns pointer to the comment summary. |
||
54 | * |
||
55 | * @return int Pointer to the token or -1 |
||
56 | */ |
||
57 | 113 | public function getCommentSummaryPointer(): int |
|
76 | |||
77 | /** |
||
78 | * Returns comment summary token. |
||
79 | * |
||
80 | * @return array Summary token array |
||
81 | */ |
||
82 | 109 | public function getCommentSummaryToken(): array |
|
86 | |||
87 | /** |
||
88 | * Check class comment summary. |
||
89 | * |
||
90 | * @return void |
||
91 | */ |
||
92 | 113 | public function checkCommentSummary(): void |
|
117 | |||
118 | /** |
||
119 | * Checks that the first character of the summary is upper case. |
||
120 | * |
||
121 | * @param array $summaryToken Token of the summary |
||
122 | * @param int $summaryPtr Pointer to the summary |
||
123 | * |
||
124 | * @return void |
||
125 | */ |
||
126 | 109 | View Code Duplication | private function checkSummaryCapitalLetter(array $summaryToken, int $summaryPtr): void |
144 | |||
145 | /** |
||
146 | * Checks if the line length of the summary is maximum 120 chars. |
||
147 | * |
||
148 | * @param array $summaryToken Token array of the summary |
||
149 | * @param int $summaryPtr Pointer of the summary |
||
150 | * |
||
151 | * @return void |
||
152 | */ |
||
153 | 109 | private function checkSummaryLineLength(array $summaryToken, int $summaryPtr): void |
|
165 | |||
166 | /** |
||
167 | * Checks if the summary is the first line of the comment. |
||
168 | * |
||
169 | * @param array $commentStartToken Token array of the comment start |
||
170 | * @param array $summaryToken Token of the summary |
||
171 | * @param int $summaryPtr Pointer to the summary |
||
172 | * |
||
173 | * @return void |
||
174 | */ |
||
175 | 109 | private function checkSummaryIsFirstLine(array $commentStartToken, array $summaryToken, int $summaryPtr): void |
|
189 | |||
190 | /** |
||
191 | * Checks the line after the summary. |
||
192 | * |
||
193 | * @param int $summaryPtr Pointer to the summary |
||
194 | * @param int $commentEndPtr Pointer to the end of the doc comment |
||
195 | * |
||
196 | * @return void |
||
197 | */ |
||
198 | 109 | private function checkLineAfterSummary(int $summaryPtr, int $commentEndPtr): void |
|
199 | { |
||
200 | 109 | $summaryToken = $this->getCommentSummaryToken(); |
|
201 | |||
202 | 109 | $nextRelevantPtr = $this->file->findNext( |
|
203 | [ |
||
204 | 109 | T_DOC_COMMENT_WHITESPACE, |
|
205 | 109 | T_DOC_COMMENT_STAR |
|
206 | ], |
||
207 | 109 | $summaryPtr + 1, |
|
208 | 109 | $commentEndPtr, |
|
209 | 109 | true |
|
210 | ); |
||
211 | |||
212 | 109 | if ($nextRelevantPtr === -1) { |
|
213 | 1 | return; |
|
214 | } |
||
215 | |||
216 | 108 | $nextRelevantToken = $this->tokens[$nextRelevantPtr]; |
|
217 | |||
218 | 108 | if (($nextRelevantToken['line'] - $summaryToken['line']) === 1) { |
|
219 | 8 | $fixLineAfterSummary = $this->file->addFixableError( |
|
220 | 8 | AbstractDocSniff::MESSAGE_NO_LINE_AFTER_SUMMARY, |
|
221 | 8 | $summaryPtr, |
|
222 | 8 | AbstractDocSniff::CODE_NO_LINE_AFTER_SUMMARY |
|
223 | ); |
||
224 | |||
225 | 8 | if ($fixLineAfterSummary) { |
|
226 | 4 | $this->fixNoLineAfterSummary(); |
|
227 | } |
||
228 | } |
||
229 | 108 | } |
|
230 | |||
231 | /** |
||
232 | * Fixes no line after summary. |
||
233 | * |
||
234 | * @return void |
||
235 | */ |
||
236 | 4 | View Code Duplication | private function fixNoLineAfterSummary(): void |
250 | |||
251 | /** |
||
252 | * Fixes summary not first statement. |
||
253 | * |
||
254 | * @return void |
||
255 | */ |
||
256 | 4 | private function fixSummaryNotFirst(): void |
|
268 | |||
269 | /** |
||
270 | * Fixes the first letter of the summary to be uppercase. |
||
271 | * |
||
272 | * @param array $summaryToken Token array of the summary |
||
273 | * @param int $summaryPtr Pointer to the summary |
||
274 | * |
||
275 | * @return void |
||
276 | */ |
||
277 | 4 | View Code Duplication | private function fixSummaryUcFirst(array $summaryToken, int $summaryPtr): void |
285 | } |
||
286 |
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.