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 |
||
19 | class File |
||
20 | { |
||
21 | /** |
||
22 | * The CodeSniffer file |
||
23 | * |
||
24 | * @var PhpCsFile |
||
25 | */ |
||
26 | private $baseFile; |
||
27 | |||
28 | /** |
||
29 | * Wrapped PHP_CodeSniffer_Fixer |
||
30 | * |
||
31 | * @var Fixer |
||
32 | */ |
||
33 | private $fixer; |
||
34 | |||
35 | /** |
||
36 | * Contains the advanced token stack |
||
37 | * |
||
38 | * @var array |
||
39 | */ |
||
40 | private $tokens; |
||
41 | |||
42 | /** |
||
43 | * File constructor. |
||
44 | * |
||
45 | * @param PhpCsFile $baseFile CodeSniffer file |
||
46 | */ |
||
47 | 121 | public function __construct(PhpCsFile $baseFile) |
|
53 | |||
54 | /** |
||
55 | * Adds the pointer to all token data arrays. |
||
56 | * |
||
57 | * @return array Advanced token stack. |
||
58 | */ |
||
59 | 121 | private function getAdvancedTokens(): array |
|
70 | |||
71 | /** |
||
72 | * Records a fixable error against a specific token in the file. |
||
73 | * |
||
74 | * @param string $error The error message. |
||
75 | * @param int $stackPtr The stack position where the error occurred. |
||
76 | * @param string $code A violation code unique to the sniff message. |
||
77 | * @param array $data Replacements for the error message. |
||
78 | * @param int $severity The severity level for this error. |
||
79 | * A value of 0 will be converted into the default severity level. |
||
80 | * |
||
81 | * @return bool Returns true if the error was recorded and should be fixed. |
||
82 | */ |
||
83 | 68 | public function addFixableError( |
|
92 | |||
93 | /** |
||
94 | * Returns the token stack for this file. |
||
95 | * |
||
96 | * @return array Return array of token data |
||
97 | */ |
||
98 | 121 | public function getTokens(): array |
|
102 | |||
103 | /** |
||
104 | * Returns the position of the previous specified token(s). |
||
105 | * |
||
106 | * If a value is specified, the previous token of the specified type(s) |
||
107 | * containing the specified value will be returned. |
||
108 | * |
||
109 | * Returns -1 if no token can be found. |
||
110 | * |
||
111 | * @param array $types The type(s) of tokens to search for. |
||
112 | * @param int $start The position to start searching from in the token stack. |
||
113 | * @param int|null $end The end position to fail if no token is found. |
||
114 | * if not specified or null, end will default to the start of the token stack. |
||
115 | * @param bool $exclude If true, find the previous token that are NOT of the types specified in $types. |
||
116 | * @param string|null $value The value that the token(s) must be equal to. |
||
117 | * If value is omitted, tokens with any value will be returned. |
||
118 | * @param bool $local If true, tokens outside the current statement will not be checked. |
||
119 | * IE. checking will stop at the previous semi-colon found. |
||
120 | * |
||
121 | * @return int Pointer to the found token |
||
122 | * |
||
123 | * @SuppressWarnings(PHPMD.BooleanArgumentFlag) |
||
124 | */ |
||
125 | 121 | View Code Duplication | public function findPrevious( |
|
|||
126 | array $types, |
||
127 | int $start, |
||
128 | $end = null, |
||
129 | bool $exclude = false, |
||
130 | $value = null, |
||
131 | bool $local = false |
||
132 | ): int { |
||
133 | 121 | $pointer = $this->baseFile->findPrevious($types, $start, $end, $exclude, $value, $local); |
|
134 | |||
135 | 121 | return $this->preparePointer($pointer); |
|
136 | } |
||
137 | |||
138 | /** |
||
139 | * Records an error against a specific token in the file. |
||
140 | * |
||
141 | * @param string $error The error message. |
||
142 | * @param int $stackPtr The stack position where the error occurred. |
||
143 | * @param string $code A violation code unique to the sniff message. |
||
144 | * @param array $data Replacements for the error message. |
||
145 | * @param int $severity The severity level for this error. A value of 0 |
||
146 | * will be converted into the default severity level. |
||
147 | * @param bool $fixable Can the error be fixed by the sniff? |
||
148 | * |
||
149 | * @return bool Returns true if setting the error was done or false |
||
150 | * |
||
151 | * @SuppressWarnings(PHPMD.BooleanArgumentFlag) |
||
152 | */ |
||
153 | 64 | public function addError( |
|
163 | |||
164 | /** |
||
165 | * Records an error against a specific line in the file. |
||
166 | * |
||
167 | * @param string $error The error message. |
||
168 | * @param int $line The line on which the error occurred. |
||
169 | * @param string $code A violation code unique to the sniff message. |
||
170 | * @param array $data Replacements for the error message. |
||
171 | * @param int $severity The severity level for this error. A value of 0 |
||
172 | * will be converted into the default severity level. |
||
173 | * |
||
174 | * @return bool Returns true of the error got recorded |
||
175 | */ |
||
176 | 12 | public function addErrorOnLine( |
|
185 | |||
186 | /** |
||
187 | * Records a warning against a specific token in the file. |
||
188 | * |
||
189 | * @param string $warning The error message. |
||
190 | * @param int $line The line on which the warning occurred. |
||
191 | * @param string $code A violation code unique to the sniff message. |
||
192 | * @param array $data Replacements for the warning message. |
||
193 | * @param int $severity The severity level for this warning. A value of 0 will |
||
194 | * will be converted into the default severity level. |
||
195 | * |
||
196 | * @return boolean Returns true if the warning got recorded |
||
197 | */ |
||
198 | public function addWarningOnLine( |
||
207 | |||
208 | /** |
||
209 | 113 | * Returns the position of the next specified token(s). |
|
210 | * |
||
211 | * If a value is specified, the next token of the specified type(s) |
||
212 | * containing the specified value will be returned. |
||
213 | * |
||
214 | * Returns false if no token can be found. |
||
215 | * |
||
216 | * @param array $types The type(s) of tokens to search for. |
||
217 | 113 | * @param int $start The position to start searching from in the |
|
218 | * token stack. |
||
219 | 113 | * @param int|null $end The end position to fail if no token is found. if not specified or null, end will default to |
|
220 | * the end of the token stack. |
||
221 | * @param bool $exclude If true, find the next token that is NOT of a type specified in $types. |
||
222 | * @param string|null $value The value that the token(s) must be equal to. |
||
223 | * If value is omitted, tokens with any value will be returned. |
||
224 | * @param bool $local If true, tokens outside the current statement will not be checked. i.e., checking will stop |
||
225 | * at the next semi-colon found. |
||
226 | * |
||
227 | * @return int Returns the pointer of the token or -1 |
||
228 | * |
||
229 | 121 | * @SuppressWarnings(PHPMD.BooleanArgumentFlag) |
|
230 | */ |
||
231 | 121 | View Code Duplication | public function findNext( |
243 | |||
244 | /** |
||
245 | * Prepares given pointer result. |
||
246 | * |
||
247 | * @param int|bool $pointer Pointer of a token |
||
248 | * |
||
249 | 87 | * @return int Pointer or -1 when not found |
|
250 | */ |
||
251 | 87 | public function preparePointer($pointer): int |
|
255 | |||
256 | /** |
||
257 | * Returns the Wrapped PHP_CodeSniffer_Fixer |
||
258 | * |
||
259 | * @return Fixer Returns the wrapped PHP_CodeSniffer_Fixer |
||
260 | */ |
||
261 | public function getFixer(): Fixer |
||
265 | |||
266 | /** |
||
267 | * Returns the eol char of the file |
||
268 | * |
||
269 | * @return string Returns the EndOfLine-Character of the processed file |
||
270 | */ |
||
271 | public function getEolChar(): string |
||
275 | } |
||
276 |
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.