1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types = 1); |
4
|
|
|
|
5
|
|
|
namespace BestIt\Sniffs\Formatting; |
6
|
|
|
|
7
|
|
|
use PHP_CodeSniffer\Files\File; |
8
|
|
|
use PHP_CodeSniffer\Sniffs\Sniff; |
9
|
|
|
|
10
|
|
|
/** |
11
|
|
|
* Class SpaceAfterDeclareSniff |
12
|
|
|
* |
13
|
|
|
* @package BestIt\Sniffs\Formatting |
14
|
|
|
* |
15
|
|
|
* @author Nick Lubisch <[email protected]> |
16
|
|
|
*/ |
17
|
|
|
class SpaceAfterDeclareSniff implements Sniff |
18
|
|
|
{ |
19
|
|
|
/** |
20
|
|
|
* Error message when no whitespace is found. |
21
|
|
|
* |
22
|
|
|
* @var string |
23
|
|
|
*/ |
24
|
|
|
const MESSAGE_NO_WHITESPACE_FOUND = 'There is no whitespace after declare-statement.'; |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* Code when no whitespace is found. |
28
|
|
|
* |
29
|
|
|
* @var string |
30
|
|
|
*/ |
31
|
|
|
const CODE_NO_WHITESPACE_FOUND = 'NoWhitespaceFound'; |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* Error message when more than one whitespaces are found. |
35
|
|
|
* |
36
|
|
|
* @var string |
37
|
|
|
*/ |
38
|
|
|
const MESSAGE_MUCH_WHITESPACE_FOUND = 'There are more than one whitespaces after declare-statement.'; |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* Code when more than one whitespaces are found. |
42
|
|
|
* |
43
|
|
|
* @var string |
44
|
|
|
*/ |
45
|
|
|
const CODE_MUCH_WHITESPACE_FOUND = 'MuchWhitespaceFound'; |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* Error message when blank lines in a group are found. |
49
|
|
|
* |
50
|
|
|
* @var string |
51
|
|
|
*/ |
52
|
5 |
|
const MESSAGE_GROUP_BLANK_LINE_FOUND = 'Multpile declare-statements should be grouped without a blank line.'; |
53
|
|
|
|
54
|
|
|
/** |
55
|
5 |
|
* Code when whitespaces in a group are found. |
56
|
|
|
* |
57
|
|
|
* @var string |
58
|
|
|
*/ |
59
|
|
|
const CODE_GROUP_BLANK_LINE_FOUND = 'GroupBlankLineFound'; |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* Registers the tokens that this sniff wants to listen for. |
63
|
|
|
* |
64
|
|
|
* @return int[] List of tokens to listen for |
65
|
|
|
*/ |
66
|
|
|
public function register(): array |
67
|
4 |
|
{ |
68
|
|
|
return [ |
69
|
4 |
|
T_DECLARE |
70
|
|
|
]; |
71
|
4 |
|
} |
72
|
|
|
|
73
|
4 |
|
/** |
74
|
4 |
|
* Called when one of the token types that this sniff is listening for is found. |
75
|
|
|
* |
76
|
4 |
|
* @param File $phpcsFile The PHP_CodeSniffer file where the token was found. |
77
|
3 |
|
* @param int $stackPtr The position in the PHP_CodeSniffer file's token stack where the token was found. |
78
|
|
|
* |
79
|
3 |
|
* @return void Optionally returns a stack pointer. |
80
|
|
|
*/ |
81
|
|
|
public function process(File $phpcsFile, $stackPtr) |
82
|
4 |
|
{ |
83
|
|
|
$tokens = $phpcsFile->getTokens(); |
84
|
4 |
|
|
85
|
1 |
|
$semicolonPtr = $phpcsFile->findEndOfStatement($stackPtr); |
86
|
|
|
|
87
|
|
|
$secondSpacePtr = $semicolonPtr + 2; |
88
|
3 |
|
$secondSpaceToken = $tokens[$secondSpacePtr]; |
89
|
|
|
|
90
|
3 |
|
$nextDeclarePtr = $phpcsFile->findNext(T_DECLARE, $semicolonPtr, null, false); |
91
|
1 |
|
|
92
|
|
|
$whiteSpaceInGroupPtr = $phpcsFile->findNext(T_WHITESPACE, $secondSpacePtr, $nextDeclarePtr, false); |
|
|
|
|
93
|
1 |
|
|
94
|
|
|
|
95
|
3 |
|
//Declare statement group detected |
96
|
|
|
if ($secondSpaceToken['code'] === T_DECLARE) { |
97
|
|
|
return; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
//Declare statement group with blank lines detected |
101
|
|
|
if ($nextDeclarePtr && $whiteSpaceInGroupPtr) { |
|
|
|
|
102
|
|
|
$this->handleBlankLineInGroup($phpcsFile, $semicolonPtr, $whiteSpaceInGroupPtr, $nextDeclarePtr); |
103
|
|
|
return; |
104
|
|
|
} |
105
|
3 |
|
|
106
|
|
|
//Single declare statement with no following whitespace detected |
107
|
3 |
|
if ($secondSpaceToken['code'] !== T_WHITESPACE) { |
108
|
3 |
|
$this->handleNoWhitespaceFound($phpcsFile, $semicolonPtr); |
109
|
3 |
|
|
110
|
3 |
|
return; |
111
|
|
|
} |
112
|
|
|
|
113
|
3 |
|
$nextNonSpacePtr = $phpcsFile->findNext(T_WHITESPACE, $secondSpacePtr, null, true); |
114
|
3 |
|
|
115
|
3 |
|
if ($nextNonSpacePtr === false) { |
116
|
3 |
|
return; |
117
|
|
|
} |
118
|
3 |
|
|
119
|
|
|
$nextNonSpaceToken = $tokens[$nextNonSpacePtr]; |
120
|
|
|
|
121
|
|
|
//Detect too many whitespaces after declare statement |
122
|
|
|
if (($nextNonSpaceToken['line'] - $secondSpaceToken['line']) > 1) { |
123
|
|
|
$this->handleMuchWhitespacesFound($phpcsFile, $semicolonPtr, $secondSpacePtr, $nextNonSpacePtr); |
124
|
|
|
|
125
|
|
|
return; |
126
|
|
|
} |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
/** |
130
|
1 |
|
* Handles when no whitespace is found. |
131
|
|
|
* |
132
|
|
|
* @param File $phpcsFile The php cs file |
133
|
|
|
* @param int $semicolonPtr Pointer to the semicolon token |
134
|
|
|
* |
135
|
|
|
* @return void |
136
|
1 |
|
*/ |
137
|
1 |
View Code Duplication |
private function handleNoWhitespaceFound(File $phpcsFile, int $semicolonPtr) |
|
|
|
|
138
|
1 |
|
{ |
139
|
1 |
|
$fixNoWhitespace = $phpcsFile->addFixableError( |
140
|
|
|
self::MESSAGE_NO_WHITESPACE_FOUND, |
141
|
|
|
$semicolonPtr, |
142
|
1 |
|
self::CODE_NO_WHITESPACE_FOUND |
143
|
1 |
|
); |
144
|
1 |
|
|
145
|
1 |
|
if ($fixNoWhitespace) { |
146
|
|
|
$phpcsFile->fixer->beginChangeset(); |
147
|
1 |
|
$phpcsFile->fixer->addNewline($semicolonPtr); |
148
|
|
|
$phpcsFile->fixer->endChangeset(); |
149
|
1 |
|
} |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
/** |
153
|
|
|
* Handles when more than one whitespaces are found. |
154
|
|
|
* |
155
|
|
|
* @param File $phpcsFile The php cs file |
156
|
|
|
* @param int $semicolonPtr Pointer to the semicolon |
157
|
|
|
* @param int $secondSpacePtr Pointer to the second space |
158
|
|
|
* @param int $nextNonSpacePtr Pointer to the next non space token |
159
|
|
|
* |
160
|
|
|
* @return void |
161
|
|
|
*/ |
162
|
|
View Code Duplication |
private function handleMuchWhitespacesFound( |
|
|
|
|
163
|
|
|
File $phpcsFile, |
164
|
|
|
int $semicolonPtr, |
165
|
|
|
int $secondSpacePtr, |
166
|
|
|
int $nextNonSpacePtr |
167
|
|
|
) { |
168
|
|
|
$fixMuchWhitespaces = $phpcsFile->addFixableError( |
169
|
|
|
self::MESSAGE_MUCH_WHITESPACE_FOUND, |
170
|
|
|
$semicolonPtr, |
171
|
|
|
self::CODE_MUCH_WHITESPACE_FOUND |
172
|
|
|
); |
173
|
|
|
|
174
|
|
|
if ($fixMuchWhitespaces) { |
175
|
|
|
$phpcsFile->fixer->beginChangeset(); |
176
|
|
|
for ($i = $secondSpacePtr; $i < $nextNonSpacePtr; $i++) { |
177
|
|
|
$phpcsFile->fixer->replaceToken($i, ''); |
178
|
|
|
} |
179
|
|
|
$phpcsFile->fixer->endChangeset(); |
180
|
|
|
} |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
/** |
184
|
|
|
* Handles blank lines found in declare group. |
185
|
|
|
* |
186
|
|
|
* @param File $phpcsFile The php cs file |
187
|
|
|
* @param int $semicolonPtr Pointer to the semicolon |
188
|
|
|
* @param int $secondSpacePtr Pointer to the second space |
189
|
|
|
* @param int $nextNonSpacePtr Pointer to the next non space token |
190
|
|
|
* |
191
|
|
|
* @return void |
192
|
|
|
*/ |
193
|
|
View Code Duplication |
private function handleBlankLineInGroup( |
|
|
|
|
194
|
|
|
File $phpcsFile, |
195
|
|
|
int $semicolonPtr, |
196
|
|
|
int $secondSpacePtr, |
197
|
|
|
int $nextNonSpacePtr |
198
|
|
|
) { |
199
|
|
|
$fixGroupBlankLines = $phpcsFile->addFixableError( |
200
|
|
|
self::MESSAGE_GROUP_BLANK_LINE_FOUND, |
201
|
|
|
$semicolonPtr, |
202
|
|
|
self::CODE_GROUP_BLANK_LINE_FOUND |
203
|
|
|
); |
204
|
|
|
|
205
|
|
|
if ($fixGroupBlankLines) { |
206
|
|
|
$phpcsFile->fixer->beginChangeset(); |
207
|
|
|
for ($i = $secondSpacePtr; $i < $nextNonSpacePtr; $i++) { |
208
|
|
|
$phpcsFile->fixer->replaceToken($i, ''); |
209
|
|
|
} |
210
|
|
|
$phpcsFile->fixer->endChangeset(); |
211
|
|
|
} |
212
|
|
|
} |
213
|
|
|
} |
214
|
|
|
|
This check looks for type mismatches where the missing type is
false
. This is usually indicative of an error condtion.Consider the follow example
This function either returns a new
DateTime
object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returnedfalse
before passing on the value to another function or method that may not be able to handle afalse
.