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:
Complex classes like PHP_CodeSniffer_Fixer often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use PHP_CodeSniffer_Fixer, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 29 | class PHP_CodeSniffer_Fixer |
||
|
|
|||
| 30 | { |
||
| 31 | |||
| 32 | /** |
||
| 33 | * Is the fixer enabled and fixing a file? |
||
| 34 | * |
||
| 35 | * Sniffs should check this value to ensure they are not |
||
| 36 | * doing extra processing to prepare for a fix when fixing is |
||
| 37 | * not required. |
||
| 38 | * |
||
| 39 | * @var boolean |
||
| 40 | */ |
||
| 41 | public $enabled = false; |
||
| 42 | |||
| 43 | /** |
||
| 44 | * The number of times we have looped over a file. |
||
| 45 | * |
||
| 46 | * @var int |
||
| 47 | */ |
||
| 48 | public $loops = 0; |
||
| 49 | |||
| 50 | /** |
||
| 51 | * The file being fixed. |
||
| 52 | * |
||
| 53 | * @var PHP_CodeSniffer_File |
||
| 54 | */ |
||
| 55 | private $_currentFile = null; |
||
| 56 | |||
| 57 | /** |
||
| 58 | * The list of tokens that make up the file contents. |
||
| 59 | * |
||
| 60 | * This is a simplified list which just contains the token content and nothing |
||
| 61 | * else. This is the array that is updated as fixes are made, not the file's |
||
| 62 | * token array. Imploding this array will give you the file content back. |
||
| 63 | * |
||
| 64 | * @var array(int => string) |
||
| 65 | */ |
||
| 66 | private $_tokens = array(); |
||
| 67 | |||
| 68 | /** |
||
| 69 | * A list of tokens that have already been fixed. |
||
| 70 | * |
||
| 71 | * We don't allow the same token to be fixed more than once each time |
||
| 72 | * through a file as this can easily cause conflicts between sniffs. |
||
| 73 | * |
||
| 74 | * @var array(int) |
||
| 75 | */ |
||
| 76 | private $_fixedTokens = array(); |
||
| 77 | |||
| 78 | /** |
||
| 79 | * The last value of each fixed token. |
||
| 80 | * |
||
| 81 | * If a token is being "fixed" back to its last value, the fix is |
||
| 82 | * probably conflicting with another. |
||
| 83 | * |
||
| 84 | * @var array(int => string) |
||
| 85 | */ |
||
| 86 | private $_oldTokenValues = array(); |
||
| 87 | |||
| 88 | /** |
||
| 89 | * A list of tokens that have been fixed during a changeset. |
||
| 90 | * |
||
| 91 | * All changes in changeset must be able to be applied, or else |
||
| 92 | * the entire changeset is rejected. |
||
| 93 | * |
||
| 94 | * @var array() |
||
| 95 | */ |
||
| 96 | private $_changeset = array(); |
||
| 97 | |||
| 98 | /** |
||
| 99 | * Is there an open changeset. |
||
| 100 | * |
||
| 101 | * @var boolean |
||
| 102 | */ |
||
| 103 | private $_inChangeset = false; |
||
| 104 | |||
| 105 | /** |
||
| 106 | * Is the current fixing loop in conflict? |
||
| 107 | * |
||
| 108 | * @var boolean |
||
| 109 | */ |
||
| 110 | private $_inConflict = false; |
||
| 111 | |||
| 112 | /** |
||
| 113 | * The number of fixes that have been performed. |
||
| 114 | * |
||
| 115 | * @var int |
||
| 116 | */ |
||
| 117 | private $_numFixes = 0; |
||
| 118 | |||
| 119 | |||
| 120 | /** |
||
| 121 | * Starts fixing a new file. |
||
| 122 | * |
||
| 123 | * @param PHP_CodeSniffer_File $phpcsFile The file being fixed. |
||
| 124 | * |
||
| 125 | * @return void |
||
| 126 | */ |
||
| 127 | public function startFile($phpcsFile) |
||
| 144 | |||
| 145 | |||
| 146 | /** |
||
| 147 | * Attempt to fix the file by processing it until no fixes are made. |
||
| 148 | * |
||
| 149 | * @return boolean |
||
| 150 | */ |
||
| 151 | public function fixFile() |
||
| 228 | |||
| 229 | |||
| 230 | /** |
||
| 231 | * Generates a text diff of the original file and the new content. |
||
| 232 | * |
||
| 233 | * @param string $filePath Optional file path to diff the file against. |
||
| 234 | * If not specified, the original version of the |
||
| 235 | * file will be used. |
||
| 236 | * @param boolean $colors Print colored output or not. |
||
| 237 | * |
||
| 238 | * @return string |
||
| 239 | */ |
||
| 240 | public function generateDiff($filePath=null, $colors=true) |
||
| 303 | |||
| 304 | |||
| 305 | /** |
||
| 306 | * Get a count of fixes that have been performed on the file. |
||
| 307 | * |
||
| 308 | * This value is reset every time a new file is started, or an existing |
||
| 309 | * file is restarted. |
||
| 310 | * |
||
| 311 | * @return int |
||
| 312 | */ |
||
| 313 | public function getFixCount() |
||
| 318 | |||
| 319 | |||
| 320 | /** |
||
| 321 | * Get the current content of the file, as a string. |
||
| 322 | * |
||
| 323 | * @return string |
||
| 324 | */ |
||
| 325 | public function getContents() |
||
| 331 | |||
| 332 | |||
| 333 | /** |
||
| 334 | * Get the current fixed content of a token. |
||
| 335 | * |
||
| 336 | * This function takes changesets into account so should be used |
||
| 337 | * instead of directly accessing the token array. |
||
| 338 | * |
||
| 339 | * @param int $stackPtr The position of the token in the token stack. |
||
| 340 | * |
||
| 341 | * @return string |
||
| 342 | */ |
||
| 343 | public function getTokenContent($stackPtr) |
||
| 354 | |||
| 355 | |||
| 356 | /** |
||
| 357 | * Start recording actions for a changeset. |
||
| 358 | * |
||
| 359 | * @return void |
||
| 360 | */ |
||
| 361 | public function beginChangeset() |
||
| 381 | |||
| 382 | |||
| 383 | /** |
||
| 384 | * Stop recording actions for a changeset, and apply logged changes. |
||
| 385 | * |
||
| 386 | * @return boolean |
||
| 387 | */ |
||
| 388 | public function endChangeset() |
||
| 428 | |||
| 429 | |||
| 430 | /** |
||
| 431 | * Stop recording actions for a changeset, and discard logged changes. |
||
| 432 | * |
||
| 433 | * @return void |
||
| 434 | */ |
||
| 435 | public function rollbackChangeset() |
||
| 463 | |||
| 464 | |||
| 465 | /** |
||
| 466 | * Replace the entire contents of a token. |
||
| 467 | * |
||
| 468 | * @param int $stackPtr The position of the token in the token stack. |
||
| 469 | * @param string $content The new content of the token. |
||
| 470 | * |
||
| 471 | * @return bool If the change was accepted. |
||
| 472 | */ |
||
| 473 | public function replaceToken($stackPtr, $content) |
||
| 590 | |||
| 591 | |||
| 592 | /** |
||
| 593 | * Reverts the previous fix made to a token. |
||
| 594 | * |
||
| 595 | * @param int $stackPtr The position of the token in the token stack. |
||
| 596 | * |
||
| 597 | * @return bool If a change was reverted. |
||
| 598 | */ |
||
| 599 | public function revertToken($stackPtr) |
||
| 645 | |||
| 646 | |||
| 647 | /** |
||
| 648 | * Replace the content of a token with a part of its current content. |
||
| 649 | * |
||
| 650 | * @param int $stackPtr The position of the token in the token stack. |
||
| 651 | * @param int $start The first character to keep. |
||
| 652 | * @param int $length The number of chacters to keep. If NULL, the content of |
||
| 653 | * the token from $start to the end of the content is kept. |
||
| 654 | * |
||
| 655 | * @return bool If the change was accepted. |
||
| 656 | */ |
||
| 657 | public function substrToken($stackPtr, $start, $length=null) |
||
| 670 | |||
| 671 | |||
| 672 | /** |
||
| 673 | * Adds a newline to end of a token's content. |
||
| 674 | * |
||
| 675 | * @param int $stackPtr The position of the token in the token stack. |
||
| 676 | * |
||
| 677 | * @return bool If the change was accepted. |
||
| 678 | */ |
||
| 679 | public function addNewline($stackPtr) |
||
| 685 | |||
| 686 | |||
| 687 | /** |
||
| 688 | * Adds a newline to the start of a token's content. |
||
| 689 | * |
||
| 690 | * @param int $stackPtr The position of the token in the token stack. |
||
| 691 | * |
||
| 692 | * @return bool If the change was accepted. |
||
| 693 | */ |
||
| 694 | public function addNewlineBefore($stackPtr) |
||
| 700 | |||
| 701 | |||
| 702 | /** |
||
| 703 | * Adds content to the end of a token's current content. |
||
| 704 | * |
||
| 705 | * @param int $stackPtr The position of the token in the token stack. |
||
| 706 | * @param string $content The content to add. |
||
| 707 | * |
||
| 708 | * @return bool If the change was accepted. |
||
| 709 | */ |
||
| 710 | public function addContent($stackPtr, $content) |
||
| 716 | |||
| 717 | |||
| 718 | /** |
||
| 719 | * Adds content to the start of a token's current content. |
||
| 720 | * |
||
| 721 | * @param int $stackPtr The position of the token in the token stack. |
||
| 722 | * @param string $content The content to add. |
||
| 723 | * |
||
| 724 | * @return bool If the change was accepted. |
||
| 725 | */ |
||
| 726 | public function addContentBefore($stackPtr, $content) |
||
| 732 | |||
| 733 | |||
| 734 | }//end class |
||
| 735 |
You can fix this by adding a namespace to your class:
When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.