Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 83 |
|
0.00% |
0 / 4 |
CRAP | |
0.00% |
0 / 1 |
SpaceyParenthesisSniff | |
0.00% |
0 / 83 |
|
0.00% |
0 / 4 |
1190 | |
0.00% |
0 / 1 |
register | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
2 | |||
process | |
0.00% |
0 / 36 |
|
0.00% |
0 / 1 |
182 | |||
processOpenParenthesis | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
90 | |||
processCloseParenthesis | |
0.00% |
0 / 24 |
|
0.00% |
0 / 1 |
132 |
1 | <?php |
2 | /** |
3 | * Make sure calling functions is spacey: |
4 | * $this->foo( $arg, $arg2 ); |
5 | * wfFoo( $arg, $arg2 ); |
6 | * |
7 | * But, wfFoo() is ok. |
8 | * |
9 | * Also disallow wfFoo( ) and wfFoo( $param ) |
10 | */ |
11 | |
12 | namespace MediaWiki\Sniffs\WhiteSpace; |
13 | |
14 | use PHP_CodeSniffer\Files\File; |
15 | use PHP_CodeSniffer\Sniffs\Sniff; |
16 | use PHP_CodeSniffer\Util\Tokens; |
17 | |
18 | class SpaceyParenthesisSniff implements Sniff { |
19 | |
20 | /** |
21 | * @inheritDoc |
22 | */ |
23 | public function register(): array { |
24 | return [ |
25 | T_OPEN_PARENTHESIS, |
26 | T_CLOSE_PARENTHESIS, |
27 | T_OPEN_SHORT_ARRAY, |
28 | T_CLOSE_SHORT_ARRAY |
29 | ]; |
30 | } |
31 | |
32 | /** |
33 | * @param File $phpcsFile |
34 | * @param int $stackPtr The current token index. |
35 | * @return void|int |
36 | */ |
37 | public function process( File $phpcsFile, $stackPtr ) { |
38 | $tokens = $phpcsFile->getTokens(); |
39 | $currentToken = $tokens[$stackPtr]; |
40 | $closer = $currentToken['parenthesis_closer'] ?? $currentToken['bracket_closer'] ?? null; |
41 | |
42 | if ( !$closer ) { |
43 | // Syntax error or live coding, bow out. |
44 | return; |
45 | } |
46 | |
47 | if ( $closer === $stackPtr ) { |
48 | $this->processCloseParenthesis( $phpcsFile, $stackPtr ); |
49 | return; |
50 | } |
51 | |
52 | if ( $tokens[$stackPtr - 1]['code'] === T_WHITESPACE |
53 | && ( $tokens[$stackPtr - 2]['code'] === T_STRING |
54 | || $tokens[$stackPtr - 2]['code'] === T_ARRAY ) |
55 | ) { |
56 | // String followed by whitespace followed by |
57 | // opening brace is probably a function call. |
58 | $bracketType = $tokens[$stackPtr - 2]['code'] === T_STRING |
59 | ? 'parenthesis of function call' |
60 | : 'bracket of array'; |
61 | $fix = $phpcsFile->addFixableWarning( |
62 | 'Space found before opening %s', |
63 | $stackPtr - 1, |
64 | 'SpaceBeforeOpeningParenthesis', |
65 | [ $bracketType ] |
66 | ); |
67 | if ( $fix ) { |
68 | $phpcsFile->fixer->replaceToken( $stackPtr - 1, '' ); |
69 | } |
70 | } |
71 | |
72 | // Shorten out as early as possible on empty parenthesis |
73 | if ( $closer === $stackPtr + 1 ) { |
74 | // Intentionally do not process the closing parenthesis again |
75 | return $stackPtr + 2; |
76 | } |
77 | |
78 | // Check for space between parentheses without any arguments |
79 | if ( $closer === $stackPtr + 2 && $tokens[$stackPtr + 1]['code'] === T_WHITESPACE ) { |
80 | $bracketType = $currentToken['code'] === T_OPEN_PARENTHESIS ? 'parentheses' : 'brackets'; |
81 | $fix = $phpcsFile->addFixableWarning( |
82 | 'Unnecessary space found within %s', |
83 | $stackPtr + 1, |
84 | 'UnnecessarySpaceBetweenParentheses', |
85 | [ $bracketType ] |
86 | ); |
87 | if ( $fix ) { |
88 | $phpcsFile->fixer->replaceToken( $stackPtr + 1, '' ); |
89 | } |
90 | |
91 | // Intentionally do not process the closing parenthesis again |
92 | return $stackPtr + 3; |
93 | } |
94 | |
95 | $this->processOpenParenthesis( $phpcsFile, $stackPtr ); |
96 | } |
97 | |
98 | /** |
99 | * @param File $phpcsFile |
100 | * @param int $stackPtr The current token index. |
101 | */ |
102 | protected function processOpenParenthesis( File $phpcsFile, int $stackPtr ): void { |
103 | $tokens = $phpcsFile->getTokens(); |
104 | $nextToken = $tokens[$stackPtr + 1]; |
105 | // No space or not single space |
106 | if ( ( $nextToken['code'] === T_WHITESPACE && |
107 | $nextToken['line'] === $tokens[$stackPtr + 2]['line'] |
108 | && $nextToken['content'] !== ' ' ) |
109 | || $nextToken['code'] !== T_WHITESPACE |
110 | ) { |
111 | $fix = $phpcsFile->addFixableWarning( |
112 | 'Single space expected after opening parenthesis', |
113 | $stackPtr + 1, |
114 | 'SingleSpaceAfterOpenParenthesis' |
115 | ); |
116 | if ( $fix ) { |
117 | if ( $nextToken['code'] === T_WHITESPACE |
118 | && $nextToken['line'] === $tokens[$stackPtr + 2]['line'] |
119 | && $nextToken['content'] !== ' ' |
120 | ) { |
121 | $phpcsFile->fixer->replaceToken( $stackPtr + 1, ' ' ); |
122 | } else { |
123 | $phpcsFile->fixer->addContent( $stackPtr, ' ' ); |
124 | } |
125 | } |
126 | } |
127 | } |
128 | |
129 | /** |
130 | * @param File $phpcsFile |
131 | * @param int $stackPtr The current token index. |
132 | */ |
133 | protected function processCloseParenthesis( File $phpcsFile, int $stackPtr ): void { |
134 | $tokens = $phpcsFile->getTokens(); |
135 | $previousToken = $tokens[$stackPtr - 1]; |
136 | |
137 | if ( ( $previousToken['code'] === T_WHITESPACE |
138 | && $previousToken['content'] === ' ' ) |
139 | || ( isset( Tokens::$commentTokens[ $previousToken['code'] ] ) |
140 | && str_ends_with( $previousToken['content'], "\n" ) ) |
141 | ) { |
142 | // If previous token was |
143 | // '(' or ' ' or a comment ending with a newline |
144 | return; |
145 | } |
146 | |
147 | // If any of the whitespace tokens immediately before this token is a newline |
148 | $ptr = $stackPtr - 1; |
149 | while ( $tokens[$ptr]['code'] === T_WHITESPACE ) { |
150 | if ( $tokens[$ptr]['content'] === $phpcsFile->eolChar ) { |
151 | return; |
152 | } |
153 | $ptr--; |
154 | } |
155 | |
156 | // If the comment before all the whitespaces immediately preceding the ')' ends with a newline |
157 | if ( isset( Tokens::$commentTokens[ $tokens[$ptr]['code'] ] ) |
158 | && str_ends_with( $tokens[$ptr]['content'], "\n" ) |
159 | ) { |
160 | return; |
161 | } |
162 | |
163 | $fix = $phpcsFile->addFixableWarning( |
164 | 'Single space expected before closing parenthesis', |
165 | $stackPtr, |
166 | 'SingleSpaceBeforeCloseParenthesis' |
167 | ); |
168 | if ( $fix ) { |
169 | if ( $previousToken['code'] === T_WHITESPACE ) { |
170 | $phpcsFile->fixer->replaceToken( $stackPtr - 1, ' ' ); |
171 | } else { |
172 | $phpcsFile->fixer->addContentBefore( $stackPtr, ' ' ); |
173 | } |
174 | } |
175 | } |
176 | } |