| Conditions | 67 |
| Paths | > 20000 |
| Total Lines | 348 |
| Code Lines | 229 |
| Lines | 126 |
| Ratio | 36.21 % |
| Changes | 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:
| 1 | <?php |
||
| 246 | protected function processParams(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $commentStart) |
||
| 247 | { |
||
| 248 | if ($this->_phpVersion === null) { |
||
| 249 | $this->_phpVersion = PHP_CodeSniffer::getConfigData('php_version'); |
||
| 250 | if ($this->_phpVersion === null) { |
||
| 251 | $this->_phpVersion = PHP_VERSION_ID; |
||
| 252 | } |
||
| 253 | } |
||
| 254 | |||
| 255 | $tokens = $phpcsFile->getTokens(); |
||
| 256 | |||
| 257 | $params = array(); |
||
| 258 | $maxType = 0; |
||
| 259 | $maxVar = 0; |
||
| 260 | foreach ($tokens[$commentStart]['comment_tags'] as $pos => $tag) { |
||
| 261 | if ($tokens[$tag]['content'] !== '@param') { |
||
| 262 | continue; |
||
| 263 | } |
||
| 264 | |||
| 265 | $type = ''; |
||
| 266 | $typeSpace = 0; |
||
| 267 | $var = ''; |
||
| 268 | $varSpace = 0; |
||
| 269 | $comment = ''; |
||
| 270 | $commentLines = array(); |
||
| 271 | if ($tokens[($tag + 2)]['code'] === T_DOC_COMMENT_STRING) { |
||
| 272 | $matches = array(); |
||
| 273 | preg_match('/([^$&.]+)(?:((?:\.\.\.)?(?:\$|&)[^\s]+)(?:(\s+)(.*))?)?/', $tokens[($tag + 2)]['content'], $matches); |
||
| 274 | |||
| 275 | if (empty($matches) === false) { |
||
| 276 | $typeLen = strlen($matches[1]); |
||
| 277 | $type = trim($matches[1]); |
||
| 278 | $typeSpace = ($typeLen - strlen($type)); |
||
| 279 | $typeLen = strlen($type); |
||
| 280 | if ($typeLen > $maxType) { |
||
| 281 | $maxType = $typeLen; |
||
| 282 | } |
||
| 283 | } |
||
| 284 | |||
| 285 | if (isset($matches[2]) === true) { |
||
| 286 | $var = $matches[2]; |
||
| 287 | $varLen = strlen($var); |
||
| 288 | if ($varLen > $maxVar) { |
||
| 289 | $maxVar = $varLen; |
||
| 290 | } |
||
| 291 | |||
| 292 | if (isset($matches[4]) === true) { |
||
| 293 | $varSpace = strlen($matches[3]); |
||
| 294 | $comment = $matches[4]; |
||
| 295 | $commentLines[] = array( |
||
| 296 | 'comment' => $comment, |
||
| 297 | 'token' => ($tag + 2), |
||
| 298 | 'indent' => $varSpace, |
||
| 299 | ); |
||
| 300 | |||
| 301 | // Any strings until the next tag belong to this comment. |
||
| 302 | if (isset($tokens[$commentStart]['comment_tags'][($pos + 1)]) === true) { |
||
| 303 | $end = $tokens[$commentStart]['comment_tags'][($pos + 1)]; |
||
| 304 | } else { |
||
| 305 | $end = $tokens[$commentStart]['comment_closer']; |
||
| 306 | } |
||
| 307 | |||
| 308 | for ($i = ($tag + 3); $i < $end; $i++) { |
||
| 309 | if ($tokens[$i]['code'] === T_DOC_COMMENT_STRING) { |
||
| 310 | $indent = 0; |
||
| 311 | if ($tokens[($i - 1)]['code'] === T_DOC_COMMENT_WHITESPACE) { |
||
| 312 | $indent = strlen($tokens[($i - 1)]['content']); |
||
| 313 | } |
||
| 314 | |||
| 315 | $comment .= ' '.$tokens[$i]['content']; |
||
| 316 | $commentLines[] = array( |
||
| 317 | 'comment' => $tokens[$i]['content'], |
||
| 318 | 'token' => $i, |
||
| 319 | 'indent' => $indent, |
||
| 320 | ); |
||
| 321 | } |
||
| 322 | } |
||
| 323 | } else { |
||
| 324 | $error = 'Missing parameter comment'; |
||
| 325 | $phpcsFile->addError($error, $tag, 'MissingParamComment'); |
||
| 326 | $commentLines[] = array('comment' => ''); |
||
| 327 | }//end if |
||
| 328 | } else { |
||
| 329 | $error = 'Missing parameter name'; |
||
| 330 | $phpcsFile->addError($error, $tag, 'MissingParamName'); |
||
| 331 | }//end if |
||
| 332 | } else { |
||
| 333 | $error = 'Missing parameter type'; |
||
| 334 | $phpcsFile->addError($error, $tag, 'MissingParamType'); |
||
| 335 | }//end if |
||
| 336 | |||
| 337 | $params[] = array( |
||
| 338 | 'tag' => $tag, |
||
| 339 | 'type' => $type, |
||
| 340 | 'var' => $var, |
||
| 341 | 'comment' => $comment, |
||
| 342 | 'commentLines' => $commentLines, |
||
| 343 | 'type_space' => $typeSpace, |
||
| 344 | 'var_space' => $varSpace, |
||
| 345 | ); |
||
| 346 | }//end foreach |
||
| 347 | |||
| 348 | $realParams = $phpcsFile->getMethodParameters($stackPtr); |
||
| 349 | $foundParams = array(); |
||
| 350 | |||
| 351 | // We want to use ... for all variable length arguments, so added |
||
| 352 | // this prefix to the variable name so comparisons are easier. |
||
| 353 | foreach ($realParams as $pos => $param) { |
||
| 354 | if ($param['variable_length'] === true) { |
||
| 355 | $realParams[$pos]['name'] = '...'.$realParams[$pos]['name']; |
||
| 356 | } |
||
| 357 | } |
||
| 358 | |||
| 359 | foreach ($params as $pos => $param) { |
||
| 360 | // If the type is empty, the whole line is empty. |
||
| 361 | if ($param['type'] === '') { |
||
| 362 | continue; |
||
| 363 | } |
||
| 364 | |||
| 365 | // Check the param type value. |
||
| 366 | $typeNames = explode('|', $param['type']); |
||
| 367 | foreach ($typeNames as $typeName) { |
||
| 368 | $suggestedName = PHP_CodeSniffer::suggestType($typeName); |
||
| 369 | if ($typeName !== $suggestedName) { |
||
| 370 | $error = 'Expected "%s" but found "%s" for parameter type'; |
||
| 371 | $data = array( |
||
| 372 | $suggestedName, |
||
| 373 | $typeName, |
||
| 374 | ); |
||
| 375 | |||
| 376 | $fix = $phpcsFile->addFixableError($error, $param['tag'], 'IncorrectParamVarName', $data); |
||
| 377 | if ($fix === true) { |
||
| 378 | $content = $suggestedName; |
||
| 379 | $content .= str_repeat(' ', $param['type_space']); |
||
| 380 | $content .= $param['var']; |
||
| 381 | $content .= str_repeat(' ', $param['var_space']); |
||
| 382 | if (isset($param['commentLines'][0]) === true) { |
||
| 383 | $content .= $param['commentLines'][0]['comment']; |
||
| 384 | } |
||
| 385 | |||
| 386 | $phpcsFile->fixer->replaceToken(($param['tag'] + 2), $content); |
||
| 387 | } |
||
| 388 | } else if (count($typeNames) === 1) { |
||
| 389 | // Check type hint for array and custom type. |
||
| 390 | $suggestedTypeHint = ''; |
||
| 391 | if (strpos($suggestedName, 'array') !== false || substr($suggestedName, -2) === '[]') { |
||
| 392 | $suggestedTypeHint = 'array'; |
||
| 393 | } else if (strpos($suggestedName, 'callable') !== false) { |
||
| 394 | $suggestedTypeHint = 'callable'; |
||
| 395 | } else if (strpos($suggestedName, 'callback') !== false) { |
||
| 396 | $suggestedTypeHint = 'callable'; |
||
| 397 | } else if (in_array($typeName, PHP_CodeSniffer::$allowedTypes) === false) { |
||
| 398 | $suggestedTypeHint = $suggestedName; |
||
| 399 | } else if ($this->_phpVersion >= 70000) { |
||
| 400 | if ($typeName === 'string') { |
||
| 401 | $suggestedTypeHint = 'string'; |
||
| 402 | } else if ($typeName === 'int' || $typeName === 'integer') { |
||
| 403 | $suggestedTypeHint = 'int'; |
||
| 404 | } else if ($typeName === 'float') { |
||
| 405 | $suggestedTypeHint = 'float'; |
||
| 406 | } else if ($typeName === 'bool' || $typeName === 'boolean') { |
||
| 407 | $suggestedTypeHint = 'bool'; |
||
| 408 | } |
||
| 409 | } |
||
| 410 | |||
| 411 | if ($suggestedTypeHint !== '' && isset($realParams[$pos]) === true) { |
||
| 412 | $typeHint = $realParams[$pos]['type_hint']; |
||
| 413 | if ($typeHint === '') { |
||
| 414 | $error = 'Type hint "%s" missing for %s'; |
||
| 415 | $data = array( |
||
| 416 | $suggestedTypeHint, |
||
| 417 | $param['var'], |
||
| 418 | ); |
||
| 419 | |||
| 420 | $errorCode = 'TypeHintMissing'; |
||
| 421 | if ($suggestedTypeHint === 'string' |
||
| 422 | || $suggestedTypeHint === 'int' |
||
| 423 | || $suggestedTypeHint === 'float' |
||
| 424 | || $suggestedTypeHint === 'bool' |
||
| 425 | ) { |
||
| 426 | $errorCode = 'Scalar'.$errorCode; |
||
| 427 | } |
||
| 428 | |||
| 429 | $phpcsFile->addError($error, $stackPtr, $errorCode, $data); |
||
| 430 | } else if ($typeHint !== substr($suggestedTypeHint, (strlen($typeHint) * -1))) { |
||
| 431 | $error = 'Expected type hint "%s"; found "%s" for %s'; |
||
| 432 | $data = array( |
||
| 433 | $suggestedTypeHint, |
||
| 434 | $typeHint, |
||
| 435 | $param['var'], |
||
| 436 | ); |
||
| 437 | $phpcsFile->addError($error, $stackPtr, 'IncorrectTypeHint', $data); |
||
| 438 | }//end if |
||
| 439 | } else if ($suggestedTypeHint === '' && isset($realParams[$pos]) === true) { |
||
| 440 | $typeHint = $realParams[$pos]['type_hint']; |
||
| 441 | if ($typeHint !== '') { |
||
| 442 | $error = 'Unknown type hint "%s" found for %s'; |
||
| 443 | $data = array( |
||
| 444 | $typeHint, |
||
| 445 | $param['var'], |
||
| 446 | ); |
||
| 447 | $phpcsFile->addError($error, $stackPtr, 'InvalidTypeHint', $data); |
||
| 448 | } |
||
| 449 | }//end if |
||
| 450 | }//end if |
||
| 451 | }//end foreach |
||
| 452 | |||
| 453 | if ($param['var'] === '') { |
||
| 454 | continue; |
||
| 455 | } |
||
| 456 | |||
| 457 | $foundParams[] = $param['var']; |
||
| 458 | |||
| 459 | // Check number of spaces after the type. |
||
| 460 | $spaces = ($maxType - strlen($param['type']) + 1); |
||
| 461 | if ($param['type_space'] !== $spaces) { |
||
| 462 | $error = 'Expected %s spaces after parameter type; %s found'; |
||
| 463 | $data = array( |
||
| 464 | $spaces, |
||
| 465 | $param['type_space'], |
||
| 466 | ); |
||
| 467 | |||
| 468 | $fix = $phpcsFile->addFixableError($error, $param['tag'], 'SpacingAfterParamType', $data); |
||
| 469 | if ($fix === true) { |
||
| 470 | $phpcsFile->fixer->beginChangeset(); |
||
| 471 | |||
| 472 | $content = $param['type']; |
||
| 473 | $content .= str_repeat(' ', $spaces); |
||
| 474 | $content .= $param['var']; |
||
| 475 | $content .= str_repeat(' ', $param['var_space']); |
||
| 476 | $content .= $param['commentLines'][0]['comment']; |
||
| 477 | $phpcsFile->fixer->replaceToken(($param['tag'] + 2), $content); |
||
| 478 | |||
| 479 | // Fix up the indent of additional comment lines. |
||
| 480 | foreach ($param['commentLines'] as $lineNum => $line) { |
||
| 481 | if ($lineNum === 0 |
||
| 482 | || $param['commentLines'][$lineNum]['indent'] === 0 |
||
| 483 | ) { |
||
| 484 | continue; |
||
| 485 | } |
||
| 486 | |||
| 487 | $newIndent = ($param['commentLines'][$lineNum]['indent'] + $spaces - $param['type_space']); |
||
| 488 | $phpcsFile->fixer->replaceToken( |
||
| 489 | ($param['commentLines'][$lineNum]['token'] - 1), |
||
| 490 | str_repeat(' ', $newIndent) |
||
| 491 | ); |
||
| 492 | } |
||
| 493 | |||
| 494 | $phpcsFile->fixer->endChangeset(); |
||
| 495 | }//end if |
||
| 496 | }//end if |
||
| 497 | |||
| 498 | // Make sure the param name is correct. |
||
| 499 | if (isset($realParams[$pos]) === true) { |
||
| 500 | $realName = $realParams[$pos]['name']; |
||
| 501 | if ($realName !== $param['var']) { |
||
| 502 | $code = 'ParamNameNoMatch'; |
||
| 503 | $data = array( |
||
| 504 | $param['var'], |
||
| 505 | $realName, |
||
| 506 | ); |
||
| 507 | |||
| 508 | $error = 'Doc comment for parameter %s does not match '; |
||
| 509 | if (strtolower($param['var']) === strtolower($realName)) { |
||
| 510 | $error .= 'case of '; |
||
| 511 | $code = 'ParamNameNoCaseMatch'; |
||
| 512 | } |
||
| 513 | |||
| 514 | $error .= 'actual variable name %s'; |
||
| 515 | |||
| 516 | $phpcsFile->addError($error, $param['tag'], $code, $data); |
||
| 517 | } |
||
| 518 | } else if (substr($param['var'], -4) !== ',...') { |
||
| 519 | // We must have an extra parameter comment. |
||
| 520 | $error = 'Superfluous parameter comment'; |
||
| 521 | $phpcsFile->addError($error, $param['tag'], 'ExtraParamComment'); |
||
| 522 | }//end if |
||
| 523 | |||
| 524 | if ($param['comment'] === '') { |
||
| 525 | continue; |
||
| 526 | } |
||
| 527 | |||
| 528 | // Check number of spaces after the var name. |
||
| 529 | $spaces = ($maxVar - strlen($param['var']) + 1); |
||
| 530 | if ($param['var_space'] !== $spaces) { |
||
| 531 | $error = 'Expected %s spaces after parameter name; %s found'; |
||
| 532 | $data = array( |
||
| 533 | $spaces, |
||
| 534 | $param['var_space'], |
||
| 535 | ); |
||
| 536 | |||
| 537 | $fix = $phpcsFile->addFixableError($error, $param['tag'], 'SpacingAfterParamName', $data); |
||
| 538 | if ($fix === true) { |
||
| 539 | $phpcsFile->fixer->beginChangeset(); |
||
| 540 | |||
| 541 | $content = $param['type']; |
||
| 542 | $content .= str_repeat(' ', $param['type_space']); |
||
| 543 | $content .= $param['var']; |
||
| 544 | $content .= str_repeat(' ', $spaces); |
||
| 545 | $content .= $param['commentLines'][0]['comment']; |
||
| 546 | $phpcsFile->fixer->replaceToken(($param['tag'] + 2), $content); |
||
| 547 | |||
| 548 | // Fix up the indent of additional comment lines. |
||
| 549 | foreach ($param['commentLines'] as $lineNum => $line) { |
||
| 550 | if ($lineNum === 0 |
||
| 551 | || $param['commentLines'][$lineNum]['indent'] === 0 |
||
| 552 | ) { |
||
| 553 | continue; |
||
| 554 | } |
||
| 555 | |||
| 556 | $newIndent = ($param['commentLines'][$lineNum]['indent'] + $spaces - $param['var_space']); |
||
| 557 | $phpcsFile->fixer->replaceToken( |
||
| 558 | ($param['commentLines'][$lineNum]['token'] - 1), |
||
| 559 | str_repeat(' ', $newIndent) |
||
| 560 | ); |
||
| 561 | } |
||
| 562 | |||
| 563 | $phpcsFile->fixer->endChangeset(); |
||
| 564 | }//end if |
||
| 565 | }//end if |
||
| 566 | |||
| 567 | // Param comments must start with a capital letter and end with the full stop. |
||
| 568 | if (preg_match('/^(\p{Ll}|\P{L})/u', $param['comment']) === 1) { |
||
| 569 | $error = 'Parameter comment must start with a capital letter'; |
||
| 570 | $phpcsFile->addError($error, $param['tag'], 'ParamCommentNotCapital'); |
||
| 571 | } |
||
| 572 | |||
| 573 | $lastChar = substr($param['comment'], -1); |
||
| 574 | if ($lastChar !== '.') { |
||
| 575 | $error = 'Parameter comment must end with a full stop'; |
||
| 576 | $phpcsFile->addError($error, $param['tag'], 'ParamCommentFullStop'); |
||
| 577 | } |
||
| 578 | }//end foreach |
||
| 579 | |||
| 580 | $realNames = array(); |
||
| 581 | foreach ($realParams as $realParam) { |
||
| 582 | $realNames[] = $realParam['name']; |
||
| 583 | } |
||
| 584 | |||
| 585 | // Report missing comments. |
||
| 586 | $diff = array_diff($realNames, $foundParams); |
||
| 587 | foreach ($diff as $neededParam) { |
||
| 588 | $error = 'Doc comment for parameter "%s" missing'; |
||
| 589 | $data = array($neededParam); |
||
| 590 | $phpcsFile->addError($error, $commentStart, 'MissingParamTag', $data); |
||
| 591 | } |
||
| 592 | |||
| 593 | }//end processParams() |
||
| 594 | |||
| 597 |