Conditions | 32 |
Paths | 4248 |
Total Lines | 123 |
Code Lines | 65 |
Lines | 0 |
Ratio | 0 % |
Tests | 60 |
CRAP Score | 32.0045 |
Changes | 3 | ||
Bugs | 0 | Features | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.
There are several approaches to avoid long parameter lists:
1 | <?php |
||
140 | 4 | protected function processSigType( |
|
141 | File $file, |
||
142 | DocBlock $docBlock, |
||
143 | string $subject, |
||
144 | TypeInterface $fnType, |
||
145 | int $fnTypeLine, |
||
146 | ?TypeInterface $docType, |
||
147 | int $docTypeLine, |
||
148 | ?TypeInterface $valueType |
||
149 | ): void { |
||
150 | 4 | $isReturnType = 'return value' === $subject; |
|
151 | 4 | $docTypeDefined = !($docType instanceof UndefinedType); |
|
152 | 4 | $fnTypeDefined = !($fnType instanceof UndefinedType); |
|
153 | |||
154 | /** @var string[][] $warnings */ |
||
155 | 4 | $warnings = []; |
|
156 | |||
157 | // func1(string $arg1 = null) -> ?string |
||
158 | 4 | if ($valueType instanceof NullType && $fnTypeDefined && !($fnType instanceof NullableType)) { |
|
159 | 1 | $warnings[$fnTypeLine][] = sprintf( |
|
160 | 1 | 'Change :subject: type declaration to nullable, e.g. %s. Remove default null value if this argument is required.', |
|
161 | 1 | (new NullableType($fnType))->toString() |
|
162 | ); |
||
163 | } |
||
164 | |||
165 | 4 | if ($docBlock instanceof UndefinedDocBlock) { |
|
166 | // Require docType for undefined type or array type |
||
167 | 3 | if ($fnType instanceof UndefinedType) { |
|
168 | 2 | $warnings[$fnTypeLine][] = 'Add type declaration for :subject: or create PHPDoc with type hint'; |
|
169 | 2 | } elseif (TypeHelper::containsType($fnType, ArrayType::class)) { |
|
170 | 3 | $warnings[$fnTypeLine][] = 'Create PHPDoc with typed array type hint for :subject:, .e.g.: "string[]" or "SomeClass[]"'; |
|
171 | } |
||
172 | 4 | } elseif (null === $docType) { |
|
173 | // Require docTag unless void return type |
||
174 | 4 | if ($isReturnType) { |
|
175 | 4 | if (!($fnType instanceof VoidType)) { |
|
176 | 4 | $warnings[$fnTypeLine][] = 'Missing PHPDoc tag or void type declaration for :subject:'; |
|
177 | } |
||
178 | } else { |
||
179 | 4 | $warnings[$fnTypeLine][] = 'Missing PHPDoc tag for :subject:'; |
|
180 | } |
||
181 | } else { |
||
182 | 4 | if ($docTypeDefined) { |
|
183 | // Require typed array type |
||
184 | // Require composite with null instead of null |
||
185 | // @TODO true/void/false/$this/ cannot be param tags |
||
186 | |||
187 | 4 | $docHasTypedArray = TypeHelper::containsType($docType, TypedArrayType::class); |
|
188 | 4 | $docHasArray = TypeHelper::containsType($docType, ArrayType::class); |
|
189 | |||
190 | 4 | if (!$docHasTypedArray && $docHasArray) { |
|
191 | 2 | $warnings[$docTypeLine][] = 'Replace array type with typed array type in PHPDoc for :subject:. Use mixed[] for generic arrays. Correct array depth must be specified.'; |
|
192 | } |
||
193 | |||
194 | 4 | if ($redundantTypes = TypeComparator::getRedundantDocTypes($docType)) { |
|
195 | 2 | $warnings[$docTypeLine][] = sprintf('Remove redundant :subject: type hints "%s"', TypeHelper::listRawTypes($redundantTypes)); |
|
196 | } |
||
197 | |||
198 | 4 | if ($docHasTypedArray && $fakeType = TypeHelper::getFakeTypedArrayType($docType)) { |
|
199 | 1 | $msg = sprintf( |
|
200 | 1 | 'Use a more specific type in typed array hint "%s" for :subject:. Correct array depth must be specified.', |
|
201 | 1 | $fakeType->toString() |
|
202 | ); |
||
203 | 1 | $warnings[$docTypeLine][] = $msg; |
|
204 | } |
||
205 | |||
206 | 4 | if ($docType instanceof NullType) { |
|
207 | 1 | if ($isReturnType) { |
|
208 | $warnings[$docTypeLine][] = 'Use void :subject :type declaration or change type to compound, e.g. SomeClass|null'; |
||
209 | } else { |
||
210 | 4 | $warnings[$docTypeLine][] = 'Change type hint for :subject: to compound, e.g. SomeClass|null'; |
|
211 | } |
||
212 | } |
||
213 | } else { |
||
214 | // Require docType (example from fnType) |
||
215 | 1 | $exampleDocType = TypeConverter::toExampleDocType($fnType); |
|
216 | 1 | if (null !== $exampleDocType) { |
|
217 | 1 | $warnings[$docTypeLine][] = sprintf('Add type hint in PHPDoc tag for :subject:, e.g. "%s"', $exampleDocType->toString()); |
|
218 | } else { |
||
219 | 1 | $warnings[$docTypeLine][] = 'Add type hint in PHPDoc tag for :subject:'; |
|
220 | } |
||
221 | } |
||
222 | |||
223 | 4 | if (!$fnTypeDefined) { |
|
224 | // Require fnType if possible (check, suggest from docType) |
||
225 | 3 | if ($suggestedFnType = TypeConverter::toExampleFnType($docType)) { |
|
226 | 2 | $warnings[$fnTypeLine][] = sprintf('Add type declaration for :subject:, e.g.: "%s"', $suggestedFnType->toString()); |
|
227 | } |
||
228 | } |
||
229 | |||
230 | 4 | if ($docTypeDefined && $fnTypeDefined) { |
|
231 | // Require to add missing types to docType, |
||
232 | 4 | if ($fnType instanceof VoidType && $docType instanceof VoidType) { |
|
233 | 1 | $warnings[$docTypeLine][] = 'Remove @return void tag, not necessary'; |
|
234 | } |
||
235 | |||
236 | /** @var TypeInterface[] $wrongDocTypes */ |
||
237 | /** @var TypeInterface[] $missingDocTypes */ |
||
238 | 4 | [$wrongDocTypes, $missingDocTypes] = TypeComparator::compare($docType, $fnType, $valueType); |
|
239 | |||
240 | 4 | if ($wrongDocTypes) { |
|
241 | 3 | $warnings[$docTypeLine][] = sprintf( |
|
242 | 3 | 'Type %s "%s" %s not compatible with :subject: type declaration', |
|
243 | 3 | isset($wrongDocTypes[1]) ? 'hints' : 'hint', |
|
244 | 3 | TypeHelper::listRawTypes($wrongDocTypes), |
|
245 | 3 | isset($wrongDocTypes[1]) ? 'are' : 'is' |
|
246 | ); |
||
247 | } |
||
248 | |||
249 | 4 | if ($missingDocTypes) { |
|
|
|||
250 | 3 | $warnings[$docTypeLine][] = sprintf( |
|
251 | 3 | 'Missing "%s" %s in :subject: type hint', |
|
252 | 3 | TypeHelper::listRawTypes($missingDocTypes), |
|
253 | 3 | isset($missingDocTypes[1]) ? 'types' : 'type' |
|
254 | ); |
||
255 | } |
||
256 | } |
||
257 | } |
||
258 | |||
259 | 4 | foreach ($warnings as $line => $lineWarnings) { |
|
260 | 4 | foreach ($lineWarnings as $warningTpl) { |
|
261 | 4 | $warning = str_replace(':subject:', $subject, $warningTpl); |
|
262 | 4 | $file->addWarningOnLine($warning, $line, 'FqcnMethodSniff'); |
|
263 | } |
||
318 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.