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 |
||
21 | final class ClassDeclarationSniff extends PEAR_Sniffs_Classes_ClassDeclarationSniff |
||
22 | { |
||
23 | |||
24 | /** |
||
25 | * @var string |
||
26 | */ |
||
27 | const NAME = 'ZenifyCodingStandard.Classes.ClassDeclaration'; |
||
28 | |||
29 | /** |
||
30 | * @var int |
||
31 | */ |
||
32 | public $emptyLinesAfterOpeningBrace = 1; |
||
33 | |||
34 | /** |
||
35 | * @var int |
||
36 | */ |
||
37 | public $emptyLinesBeforeClosingBrace = 1; |
||
38 | |||
39 | /** |
||
40 | * @var PHP_CodeSniffer_File |
||
41 | */ |
||
42 | private $file; |
||
43 | |||
44 | |||
45 | /** |
||
46 | * @param PHP_CodeSniffer_File $file |
||
47 | * @param int $position |
||
48 | */ |
||
49 | 2 | public function process(PHP_CodeSniffer_File $file, $position) |
|
50 | { |
||
51 | 2 | parent::process($file, $position); |
|
52 | 2 | $this->file = $file; |
|
53 | |||
54 | // Fix type |
||
55 | 2 | $this->emptyLinesAfterOpeningBrace = (int) $this->emptyLinesAfterOpeningBrace; |
|
56 | 2 | $this->emptyLinesBeforeClosingBrace = (int) $this->emptyLinesBeforeClosingBrace; |
|
57 | |||
58 | 2 | $this->processOpen($file, $position); |
|
59 | 2 | $this->processClose($file, $position); |
|
60 | 2 | } |
|
61 | |||
62 | |||
63 | 2 | View Code Duplication | private function processOpen(PHP_CodeSniffer_File $file, int $position) |
64 | { |
||
65 | 2 | $tokens = $file->getTokens(); |
|
66 | 2 | $openingBracePosition = $tokens[$position]['scope_opener']; |
|
67 | 2 | $emptyLinesCount = $this->getEmptyLinesAfterOpeningBrace($file, $openingBracePosition); |
|
68 | |||
69 | 2 | if ($emptyLinesCount !== $this->emptyLinesAfterOpeningBrace) { |
|
70 | 2 | $error = 'Opening brace for the %s should be followed by %s empty line(s); %s found.'; |
|
71 | $data = [ |
||
72 | 2 | $tokens[$position]['content'], |
|
73 | 2 | $this->emptyLinesAfterOpeningBrace, |
|
74 | 2 | $emptyLinesCount, |
|
75 | ]; |
||
76 | 2 | $fix = $file->addFixableError($error, $openingBracePosition, 'OpenBraceFollowedByEmptyLines', $data); |
|
77 | 2 | if ($fix) { |
|
78 | 1 | $this->fixOpeningBraceSpaces($openingBracePosition, $emptyLinesCount); |
|
79 | } |
||
80 | } |
||
81 | 2 | } |
|
82 | |||
83 | |||
84 | 2 | View Code Duplication | private function processClose(PHP_CodeSniffer_File $file, int $position) |
85 | { |
||
86 | 2 | $tokens = $file->getTokens(); |
|
87 | 2 | $closeBracePosition = $tokens[$position]['scope_closer']; |
|
88 | 2 | $emptyLinesCount = $this->getEmptyLinesBeforeClosingBrace($file, $closeBracePosition); |
|
89 | |||
90 | 2 | if ($emptyLinesCount !== $this->emptyLinesBeforeClosingBrace) { |
|
91 | 2 | $error = 'Closing brace for the %s should be preceded by %s empty line(s); %s found.'; |
|
92 | $data = [ |
||
93 | 2 | $tokens[$position]['content'], |
|
94 | 2 | $this->emptyLinesBeforeClosingBrace, |
|
95 | 2 | $emptyLinesCount |
|
96 | ]; |
||
97 | 2 | $fix = $file->addFixableError($error, $closeBracePosition, 'CloseBracePrecededByEmptyLines', $data); |
|
98 | 2 | if ($fix) { |
|
99 | 1 | $this->fixClosingBraceSpaces($closeBracePosition, $emptyLinesCount); |
|
100 | } |
||
101 | } |
||
102 | 2 | } |
|
103 | |||
104 | |||
105 | 2 | private function getEmptyLinesBeforeClosingBrace(PHP_CodeSniffer_File $file, int $position) : int |
|
106 | { |
||
107 | 2 | $tokens = $file->getTokens(); |
|
108 | 2 | $prevContent = $file->findPrevious(T_WHITESPACE, ($position - 1), NULL, TRUE); |
|
109 | 2 | return $tokens[$position]['line'] - $tokens[$prevContent]['line'] - 1; |
|
110 | } |
||
111 | |||
112 | |||
113 | 2 | private function getEmptyLinesAfterOpeningBrace(PHP_CodeSniffer_File $file, int $position) : int |
|
119 | |||
120 | |||
121 | 1 | View Code Duplication | private function fixOpeningBraceSpaces(int $position, int $numberOfSpaces) |
122 | { |
||
123 | 1 | if ($numberOfSpaces < $this->emptyLinesAfterOpeningBrace) { |
|
134 | |||
135 | |||
136 | 1 | View Code Duplication | private function fixClosingBraceSpaces(int $position, int $numberOfSpaces) |
149 | |||
150 | } |
||
151 |