Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 47 |
|
0.00% |
0 / 3 |
CRAP | |
0.00% |
0 / 1 |
TrailingCommaSniff | |
0.00% |
0 / 47 |
|
0.00% |
0 / 3 |
272 | |
0.00% |
0 / 1 |
register | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
process | |
0.00% |
0 / 30 |
|
0.00% |
0 / 1 |
72 | |||
checkWarnAndFix | |
0.00% |
0 / 16 |
|
0.00% |
0 / 1 |
56 |
1 | <?php |
2 | |
3 | /** |
4 | * This program is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License as published by |
6 | * the Free Software Foundation; either version 2 of the License, or |
7 | * (at your option) any later version. |
8 | * |
9 | * This program is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU General Public License along |
15 | * with this program; if not, write to the Free Software Foundation, Inc., |
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
17 | * http://www.gnu.org/copyleft/gpl.html |
18 | * |
19 | * @file |
20 | */ |
21 | |
22 | namespace MediaWiki\Sniffs\Arrays; |
23 | |
24 | use PHP_CodeSniffer\Files\File; |
25 | use PHP_CodeSniffer\Sniffs\Sniff; |
26 | use PHP_CodeSniffer\Util\Tokens; |
27 | |
28 | /** |
29 | * Sniff to enforce the presence or absence of trailing commas in single- and multi-line arrays. |
30 | * |
31 | * By default, this sniff does nothing. |
32 | * Configure it as follows to enforce trailing commas in multi-line arrays |
33 | * while removing them in single-line arrays: |
34 | * <rule ref="MediaWiki.Arrays.TrailingComma"> |
35 | * <properties> |
36 | * <property name="singleLine" value="false" /> |
37 | * <property name="multiLine" value="true" /> |
38 | * </properties> |
39 | * </rule> |
40 | */ |
41 | class TrailingCommaSniff implements Sniff { |
42 | |
43 | /** |
44 | * Enforce the presence (true) or absence (false) of trailing commas in single-line arrays. |
45 | * By default (null), do nothing. |
46 | * @var bool|null |
47 | */ |
48 | public ?bool $singleLine = null; |
49 | |
50 | /** |
51 | * Enforce the presence (true) or absence (false) of trailing commas in multi-line arrays. |
52 | * By default (null), do nothing. |
53 | * @var bool|null |
54 | */ |
55 | public ?bool $multiLine = null; |
56 | |
57 | public function register(): array { |
58 | return [ T_CLOSE_SHORT_ARRAY ]; |
59 | } |
60 | |
61 | /** |
62 | * @param File $phpcsFile |
63 | * @param int $stackPtr The current token index. |
64 | * @return void|int |
65 | */ |
66 | public function process( File $phpcsFile, $stackPtr ) { |
67 | if ( $this->singleLine === null && $this->multiLine === null ) { |
68 | // not configured to do anything, skip to end of file |
69 | return $phpcsFile->numTokens; |
70 | } |
71 | |
72 | $tokens = $phpcsFile->getTokens(); |
73 | |
74 | $lastContentToken = $phpcsFile->findPrevious( |
75 | Tokens::$emptyTokens, |
76 | $stackPtr - 1, |
77 | null, |
78 | true |
79 | ); |
80 | |
81 | $isEmptyArray = $tokens[$lastContentToken]['code'] === T_OPEN_SHORT_ARRAY; |
82 | if ( $isEmptyArray ) { |
83 | // PHP syntax doesn't allow [,] so we can stop early |
84 | return; |
85 | } |
86 | |
87 | $isMultiline = false; |
88 | for ( $token = $lastContentToken + 1; $token < $stackPtr; $token++ ) { |
89 | if ( str_contains( $tokens[$token]['content'], "\n" ) ) { |
90 | $isMultiline = true; |
91 | break; |
92 | } |
93 | } |
94 | |
95 | if ( $isMultiline ) { |
96 | $wantTrailingComma = $this->multiLine; |
97 | } else { |
98 | $wantTrailingComma = $this->singleLine; |
99 | } |
100 | if ( $wantTrailingComma === null ) { |
101 | return; |
102 | } |
103 | |
104 | $hasTrailingComma = $tokens[$lastContentToken]['code'] === T_COMMA; |
105 | |
106 | $this->checkWarnAndFix( |
107 | $phpcsFile, |
108 | $lastContentToken, |
109 | $hasTrailingComma, |
110 | $wantTrailingComma, |
111 | $isMultiline |
112 | ); |
113 | } |
114 | |
115 | /** |
116 | * Check whether a warning should be emitted, |
117 | * emit one if necessary, and fix it if requested. |
118 | * |
119 | * @param File $phpcsFile |
120 | * @param int $token |
121 | * @param bool $hasTrailingComma Whether the trailing comma *is* present. |
122 | * @param bool $wantTrailingComma Whether the trailing comma *should* be present. |
123 | * @param bool $isMultiline Whether the array is multi-line or single-line. |
124 | * (Only used for the warning message and code at this point.) |
125 | */ |
126 | private function checkWarnAndFix( |
127 | File $phpcsFile, |
128 | int $token, |
129 | bool $hasTrailingComma, |
130 | bool $wantTrailingComma, |
131 | bool $isMultiline |
132 | ): void { |
133 | if ( $hasTrailingComma === $wantTrailingComma ) { |
134 | return; |
135 | } |
136 | |
137 | // possible messages (for grepping): |
138 | // Multi-line array with trailing comma |
139 | // Multi-line array without trailing comma |
140 | // Single-line array with trailing comma |
141 | // Single-line array without trailing comma |
142 | $fix = $phpcsFile->addFixableWarning( |
143 | '%s array %s trailing comma', |
144 | $token, |
145 | $isMultiline ? 'MultiLine' : 'SingleLine', |
146 | [ |
147 | $isMultiline ? 'Multi-line' : 'Single-line', |
148 | $wantTrailingComma ? 'without' : 'with', |
149 | ] |
150 | ); |
151 | if ( !$fix ) { |
152 | return; |
153 | } |
154 | |
155 | // adding/removing the trailing comma works the same regardless of $isMultiline |
156 | if ( $wantTrailingComma ) { |
157 | $phpcsFile->fixer->addContent( $token, ',' ); |
158 | } else { |
159 | $phpcsFile->fixer->replaceToken( $token, '' ); |
160 | } |
161 | } |
162 | |
163 | } |