Complex classes like Validator 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 Validator, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 31 | class Validator |
||
| 32 | { |
||
| 33 | /** |
||
| 34 | * Verify template |
||
| 35 | * |
||
| 36 | * @param array<string,array|string|integer> $context Current context |
||
| 37 | * @param string $template handlebars template |
||
| 38 | */ |
||
| 39 | 794 | public static function verify(&$context, $template) |
|
| 77 | |||
| 78 | /** |
||
| 79 | * push left string of current token and clear it |
||
| 80 | * |
||
| 81 | * @param array<string,array|string|integer> $context Current context |
||
| 82 | */ |
||
| 83 | 781 | protected static function pushLeft(&$context) |
|
| 89 | |||
| 90 | /** |
||
| 91 | * push a string into the partial stacks |
||
| 92 | * |
||
| 93 | * @param array<string,array|string|integer> $context Current context |
||
| 94 | * @param string $append a string to be appended int partial stacks |
||
| 95 | */ |
||
| 96 | 783 | protected static function pushPartial(&$context, $append) |
|
| 104 | |||
| 105 | /** |
||
| 106 | * push a token into the stack when it is not empty string |
||
| 107 | * |
||
| 108 | * @param array<string,array|string|integer> $context Current context |
||
| 109 | * @param string|array $token a parsed token or a string |
||
| 110 | */ |
||
| 111 | 794 | protected static function pushToken(&$context, $token) |
|
| 136 | |||
| 137 | /** |
||
| 138 | * push current token into the section stack |
||
| 139 | * |
||
| 140 | * @param array<string,array|string|integer> $context Current context |
||
| 141 | * @param string $operation operation string |
||
| 142 | * @param array<boolean|integer|string|array> $vars parsed arguments list |
||
| 143 | */ |
||
| 144 | 394 | protected static function pushStack(&$context, $operation, $vars) |
|
| 152 | |||
| 153 | /** |
||
| 154 | * Verify delimiters and operators |
||
| 155 | * |
||
| 156 | * @param string[] $token detected handlebars {{ }} token |
||
| 157 | * @param array<string,array|string|integer> $context current compile context |
||
| 158 | * |
||
| 159 | * @return boolean|null Return true when invalid |
||
| 160 | * |
||
| 161 | * @expect null when input array_fill(0, 11, ''), array() |
||
| 162 | * @expect null when input array(0, 0, 0, 0, 0, '{{', '#', '...', '}}'), array() |
||
| 163 | * @expect true when input array(0, 0, 0, 0, 0, '{', '#', '...', '}'), array() |
||
| 164 | */ |
||
| 165 | 782 | protected static function delimiter($token, &$context) |
|
| 178 | |||
| 179 | /** |
||
| 180 | * Verify operators |
||
| 181 | * |
||
| 182 | * @param string $operator the operator string |
||
| 183 | * @param array<string,array|string|integer> $context current compile context |
||
| 184 | * @param array<boolean|integer|string|array> $vars parsed arguments list |
||
| 185 | * |
||
| 186 | * @return boolean|integer|null Return true when invalid or detected |
||
| 187 | * |
||
| 188 | * @expect null when input '', array(), array() |
||
| 189 | * @expect 2 when input '^', array('usedFeature' => array('isec' => 1), 'level' => 0, 'currentToken' => array(0,0,0,0,0,0,0,0), 'elselvl' => array(), 'flags' => array('spvar' => 0), 'elsechain' => false, 'helperresolver' => 0), array(array('foo')) |
||
| 190 | * @expect true when input '/', array('stack' => array('[with]', '#'), 'level' => 1, 'currentToken' => array(0,0,0,0,0,0,0,'with'), 'flags' => array('nohbh' => 0)), array(array()) |
||
| 191 | * @expect 4 when input '#', array('usedFeature' => array('sec' => 3), 'level' => 0, 'currentToken' => array(0,0,0,0,0,0,0,0), 'flags' => array('spvar' => 0), 'elsechain' => false, 'elselvl' => array(), 'helperresolver' => 0), array(array('x')) |
||
| 192 | * @expect 5 when input '#', array('usedFeature' => array('if' => 4), 'level' => 0, 'currentToken' => array(0,0,0,0,0,0,0,0), 'flags' => array('spvar' => 0, 'nohbh' => 0), 'elsechain' => false, 'elselvl' => array(), 'helperresolver' => 0), array(array('if')) |
||
| 193 | * @expect 6 when input '#', array('usedFeature' => array('with' => 5), 'level' => 0, 'flags' => array('nohbh' => 0, 'runpart' => 0, 'spvar' => 0), 'currentToken' => array(0,0,0,0,0,0,0,0), 'elsechain' => false, 'elselvl' => array(), 'helperresolver' => 0), array(array('with')) |
||
| 194 | * @expect 7 when input '#', array('usedFeature' => array('each' => 6), 'level' => 0, 'currentToken' => array(0,0,0,0,0,0,0,0), 'flags' => array('spvar' => 0, 'nohbh' => 0), 'elsechain' => false, 'elselvl' => array(), 'helperresolver' => 0), array(array('each')) |
||
| 195 | * @expect 8 when input '#', array('usedFeature' => array('unless' => 7), 'level' => 0, 'currentToken' => array(0,0,0,0,0,0,0,0), 'flags' => array('spvar' => 0, 'nohbh' => 0), 'elsechain' => false, 'elselvl' => array(), 'helperresolver' => 0), array(array('unless')) |
||
| 196 | * @expect 9 when input '#', array('helpers' => array('abc' => ''), 'usedFeature' => array('helper' => 8), 'level' => 0, 'currentToken' => array(0,0,0,0,0,0,0,0), 'flags' => array('spvar' => 0), 'elsechain' => false, 'elselvl' => array()), array(array('abc')) |
||
| 197 | * @expect 11 when input '#', array('helpers' => array('abc' => ''), 'usedFeature' => array('helper' => 10), 'level' => 0, 'currentToken' => array(0,0,0,0,0,0,0,0), 'flags' => array('spvar' => 0), 'elsechain' => false, 'elselvl' => array()), array(array('abc')) |
||
| 198 | * @expect true when input '>', array('partialresolver' => false, 'usedFeature' => array('partial' => 7), 'level' => 0, 'flags' => array('skippartial' => 0, 'runpart' => 0, 'spvar' => 0), 'currentToken' => array(0,0,0,0,0,0,0,0), 'elsechain' => false, 'elselvl' => array()), array('test') |
||
| 199 | */ |
||
| 200 | 743 | protected static function operator($operator, &$context, &$vars) |
|
| 260 | |||
| 261 | /** |
||
| 262 | * validate inline partial begin token |
||
| 263 | * |
||
| 264 | * @param array<string,array|string|integer> $context current compile context |
||
| 265 | * @param array<boolean|integer|string|array> $vars parsed arguments list |
||
| 266 | * |
||
| 267 | * @return boolean|null Return true when inline partial ends |
||
| 268 | */ |
||
| 269 | 742 | protected static function inlinePartial(&$context, $vars) |
|
| 288 | |||
| 289 | /** |
||
| 290 | * validate partial block token |
||
| 291 | * |
||
| 292 | * @param array<string,array|string|integer> $context current compile context |
||
| 293 | * @param array<boolean|integer|string|array> $vars parsed arguments list |
||
| 294 | * |
||
| 295 | * @return boolean|null Return true when partial block ends |
||
| 296 | */ |
||
| 297 | 742 | protected static function partialBlock(&$context, $vars) |
|
| 323 | |||
| 324 | /** |
||
| 325 | * handle else chain |
||
| 326 | * |
||
| 327 | * @param array<string,array|string|integer> $context current compile context |
||
| 328 | */ |
||
| 329 | 366 | protected static function doElseChain(&$context) |
|
| 337 | |||
| 338 | /** |
||
| 339 | * validate block begin token |
||
| 340 | * |
||
| 341 | * @param array<string,array|string|integer> $context current compile context |
||
| 342 | * @param array<boolean|integer|string|array> $vars parsed arguments list |
||
| 343 | * |
||
| 344 | * @return boolean Return true always |
||
| 345 | */ |
||
| 346 | 281 | protected static function blockBegin(&$context, $vars) |
|
| 361 | |||
| 362 | /** |
||
| 363 | * validate builtin helpers |
||
| 364 | * |
||
| 365 | * @param array<string,array|string|integer> $context current compile context |
||
| 366 | * @param array<boolean|integer|string|array> $vars parsed arguments list |
||
| 367 | */ |
||
| 368 | 165 | protected static function builtin(&$context, $vars) |
|
| 381 | |||
| 382 | /** |
||
| 383 | * validate section token |
||
| 384 | * |
||
| 385 | * @param array<string,array|string|integer> $context current compile context |
||
| 386 | * @param array<boolean|integer|string|array> $vars parsed arguments list |
||
| 387 | * @param boolean $isEach the section is #each |
||
| 388 | * |
||
| 389 | * @return boolean Return true always |
||
| 390 | */ |
||
| 391 | 184 | protected static function section(&$context, $vars, $isEach = false) |
|
| 403 | |||
| 404 | /** |
||
| 405 | * validate with token |
||
| 406 | * |
||
| 407 | * @param array<string,array|string|integer> $context current compile context |
||
| 408 | * @param array<boolean|integer|string|array> $vars parsed arguments list |
||
| 409 | * |
||
| 410 | * @return boolean Return true always |
||
| 411 | */ |
||
| 412 | 36 | protected static function with(&$context, $vars) |
|
| 417 | |||
| 418 | /** |
||
| 419 | * validate unless token |
||
| 420 | * |
||
| 421 | * @param array<string,array|string|integer> $context current compile context |
||
| 422 | * @param array<boolean|integer|string|array> $vars parsed arguments list |
||
| 423 | * |
||
| 424 | * @return boolean Return true always |
||
| 425 | */ |
||
| 426 | 7 | protected static function unless(&$context, $vars) |
|
| 431 | |||
| 432 | /** |
||
| 433 | * validate if token |
||
| 434 | * |
||
| 435 | * @param array<string,array|string|integer> $context current compile context |
||
| 436 | * @param array<boolean|integer|string|array> $vars parsed arguments list |
||
| 437 | * |
||
| 438 | * @return boolean Return true always |
||
| 439 | */ |
||
| 440 | 80 | protected static function doIf(&$context, $vars) |
|
| 445 | |||
| 446 | /** |
||
| 447 | * validate block custom helper token |
||
| 448 | * |
||
| 449 | * @param array<string,array|string|integer> $context current compile context |
||
| 450 | * @param array<boolean|integer|string|array> $vars parsed arguments list |
||
| 451 | * @param boolean $inverted the logic will be inverted |
||
| 452 | * |
||
| 453 | * @return integer|null Return number of used custom helpers |
||
| 454 | */ |
||
| 455 | 64 | protected static function blockCustomHelper(&$context, $vars, $inverted = false) |
|
| 463 | |||
| 464 | /** |
||
| 465 | * validate inverted section |
||
| 466 | * |
||
| 467 | * @param array<string,array|string|integer> $context current compile context |
||
| 468 | * @param array<boolean|integer|string|array> $vars parsed arguments list |
||
| 469 | * |
||
| 470 | * @return integer Return number of inverted sections |
||
| 471 | */ |
||
| 472 | 38 | protected static function invertedSection(&$context, $vars) |
|
| 476 | |||
| 477 | /** |
||
| 478 | * Return compiled PHP code for a handlebars block end token |
||
| 479 | * |
||
| 480 | * @param array<string,array|string|integer> $context current compile context |
||
| 481 | * @param array<boolean|integer|string|array> $vars parsed arguments list |
||
| 482 | * @param string|null $match should also match to this operator |
||
| 483 | * |
||
| 484 | * @return boolean|integer Return true when required block ended, or Token::POS_BACKFILL when backfill happened. |
||
| 485 | */ |
||
| 486 | 387 | protected static function blockEnd(&$context, &$vars, $match = null) |
|
| 532 | |||
| 533 | /** |
||
| 534 | * handle delimiter change |
||
| 535 | * |
||
| 536 | * @param array<string,array|string|integer> $context current compile context |
||
| 537 | * |
||
| 538 | * @return boolean|null Return true when delimiter changed |
||
| 539 | */ |
||
| 540 | 771 | protected static function isDelimiter(&$context) |
|
| 548 | |||
| 549 | /** |
||
| 550 | * handle raw block |
||
| 551 | * |
||
| 552 | * @param string[] $token detected handlebars {{ }} token |
||
| 553 | * @param array<string,array|string|integer> $context current compile context |
||
| 554 | * |
||
| 555 | * @return boolean|null Return true when in rawblock mode |
||
| 556 | */ |
||
| 557 | 781 | protected static function rawblock(&$token, &$context) |
|
| 588 | |||
| 589 | /** |
||
| 590 | * handle comment |
||
| 591 | * |
||
| 592 | * @param string[] $token detected handlebars {{ }} token |
||
| 593 | * @param array<string,array|string|integer> $context current compile context |
||
| 594 | * |
||
| 595 | * @return boolean|null Return true when is comment |
||
| 596 | */ |
||
| 597 | 762 | protected static function comment(&$token, &$context) |
|
| 604 | |||
| 605 | /** |
||
| 606 | * Collect handlebars usage information, detect template error. |
||
| 607 | * |
||
| 608 | * @param string[] $token detected handlebars {{ }} token |
||
| 609 | * @param array<string,array|string|integer> $context current compile context |
||
| 610 | * |
||
| 611 | * @return string|array<string,array|string|integer>|null $token string when rawblock; array when valid token require to be compiled, null when skip the token. |
||
| 612 | */ |
||
| 613 | 781 | protected static function token(&$token, &$context) |
|
| 690 | |||
| 691 | /** |
||
| 692 | * Return 1 or larger number when else token detected |
||
| 693 | * |
||
| 694 | * @param array<string,array|string|integer> $context current compile context |
||
| 695 | * @param array<boolean|integer|string|array> $vars parsed arguments list |
||
| 696 | * |
||
| 697 | * @return integer Return 1 or larger number when else token detected |
||
| 698 | */ |
||
| 699 | 61 | protected static function doElse(&$context, $vars) |
|
| 715 | |||
| 716 | /** |
||
| 717 | * Return true when this is {{log ...}} |
||
| 718 | * |
||
| 719 | * @param array<string,array|string|integer> $context current compile context |
||
| 720 | * @param array<boolean|integer|string|array> $vars parsed arguments list |
||
| 721 | * |
||
| 722 | * @return boolean|null Return true when it is custom helper |
||
| 723 | */ |
||
| 724 | 373 | public static function log(&$context, $vars) |
|
| 736 | |||
| 737 | /** |
||
| 738 | * Return true when this is {{lookup ...}} |
||
| 739 | * |
||
| 740 | * @param array<string,array|string|integer> $context current compile context |
||
| 741 | * @param array<boolean|integer|string|array> $vars parsed arguments list |
||
| 742 | * |
||
| 743 | * @return boolean|null Return true when it is custom helper |
||
| 744 | */ |
||
| 745 | 373 | public static function lookup(&$context, $vars) |
|
| 759 | |||
| 760 | /** |
||
| 761 | * Return true when the name is listed in helper table |
||
| 762 | * |
||
| 763 | * @param array<string,array|string|integer> $context current compile context |
||
| 764 | * @param array<boolean|integer|string|array> $vars parsed arguments list |
||
| 765 | * @param boolean $checkSubexp true when check for subexpression |
||
| 766 | * |
||
| 767 | * @return boolean Return true when it is custom helper |
||
| 768 | */ |
||
| 769 | 499 | public static function helper(&$context, $vars, $checkSubexp = false) |
|
| 789 | |||
| 790 | /** |
||
| 791 | * use helperresolver to resolve helper, return true when helper founded |
||
| 792 | * |
||
| 793 | * @param array<string,array|string|integer> $context Current context of compiler progress. |
||
| 794 | * @param array<boolean|integer|string|array> $vars parsed arguments list |
||
| 795 | * |
||
| 796 | * @return boolean $found helper exists or not |
||
| 797 | */ |
||
| 798 | 668 | public static function resolveHelper(&$context, &$vars) |
|
| 817 | |||
| 818 | /** |
||
| 819 | * detect for block custom helper |
||
| 820 | * |
||
| 821 | * @param array<string,array|string|integer> $context current compile context |
||
| 822 | * @param array<boolean|integer|string|array> $vars parsed arguments list |
||
| 823 | * |
||
| 824 | * @return boolean|null Return true when this token is block custom helper |
||
| 825 | */ |
||
| 826 | 366 | protected static function isBlockHelper($context, $vars) |
|
| 838 | |||
| 839 | /** |
||
| 840 | * validate inline partial |
||
| 841 | * |
||
| 842 | * @param array<string,array|string|integer> $context current compile context |
||
| 843 | * @param array<boolean|integer|string|array> $vars parsed arguments list |
||
| 844 | * |
||
| 845 | * @return boolean Return true always |
||
| 846 | */ |
||
| 847 | 16 | protected static function inline(&$context, $vars) |
|
| 860 | |||
| 861 | /** |
||
| 862 | * validate partial |
||
| 863 | * |
||
| 864 | * @param array<string,array|string|integer> $context current compile context |
||
| 865 | * @param array<boolean|integer|string|array> $vars parsed arguments list |
||
| 866 | * |
||
| 867 | * @return integer|boolean Return 1 or larger number for runtime partial, return true for other case |
||
| 868 | */ |
||
| 869 | 118 | protected static function partial(&$context, $vars) |
|
| 892 | |||
| 893 | /** |
||
| 894 | * Modify $token when spacing rules matched. |
||
| 895 | * |
||
| 896 | * @param array<string> $token detected handlebars {{ }} token |
||
| 897 | * @param array<string,array|string|integer> $context current compile context |
||
| 898 | * @param boolean $nost do not do stand alone logic |
||
| 899 | * |
||
| 900 | * @return string|null Return compiled code segment for the token |
||
| 901 | */ |
||
| 902 | 771 | protected static function spacing(&$token, &$context, $nost = false) |
|
| 955 | } |
||
| 956 |
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.
Both the
$myVarassignment in line 1 and the$higherassignment in line 2 are dead. The first because$myVaris never used and the second because$higheris always overwritten for every possible time line.