@@ -67,7 +67,7 @@ class LineLengthSniff implements Sniff
67
67
*
68
68
* @var integer
69
69
*/
70
- public $ lineLimit = 120 ;
70
+ public $ lineLimit = 100 ;
71
71
72
72
/**
73
73
* @inheritdoc
@@ -82,167 +82,168 @@ public function register()
82
82
*/
83
83
public function process (File $ file , $ position )
84
84
{
85
- $ tokens = $ file ->getTokens ();
86
- $ start = max (1 , $ position );
87
- for ($ i = $ start ; $ i < $ file ->numTokens ; $ i ++) {
88
- if ($ tokens [$ i ]['column ' ] === 1 ) {
89
- $ this ->checkLineLength ($ file , $ tokens , $ i );
90
- }
85
+ $ longLinesData = $ this ->collectLongLinesData ($ file , max (1 , $ position ));
86
+ if (!$ longLinesData ) {
87
+ return $ file ->numTokens + 1 ;
91
88
}
92
89
93
- $ this ->checkLineLength ($ file , $ tokens , $ i );
90
+ // phpcs:disable VariableAnalysis
91
+ foreach ($ longLinesData as $ lineNum => list ($ length , $ start , $ end )) {
92
+ if ($ this ->shouldIgnoreLine ($ file , $ start , $ end )) {
93
+ continue ;
94
+ }
95
+
96
+ $ file ->addWarning (
97
+ sprintf (
98
+ 'Line %d exceeds %s characters; contains %s characters. ' ,
99
+ $ lineNum ,
100
+ $ this ->lineLimit ,
101
+ $ length
102
+ ),
103
+ $ end ,
104
+ 'TooLong '
105
+ );
106
+ }
107
+ // phpcs:enable
94
108
95
- return ( $ file ->numTokens + 1 ) ;
109
+ return $ file ->numTokens + 1 ;
96
110
}
97
111
98
112
/**
99
113
* @param File $file
100
- * @param array $tokens
101
- * @param int $position
114
+ * @param int $start
115
+ * @return array
102
116
*/
103
- protected function checkLineLength (File $ file , array $ tokens , int $ position )
117
+ protected function collectLongLinesData (File $ file , int $ start ): array
104
118
{
105
- // The passed token is the first on the line.
106
- $ position --;
107
-
108
- if ($ tokens [$ position ]['column ' ] === 1
109
- && $ tokens [$ position ]['length ' ] === 0
110
- ) {
111
- // Blank line.
112
- return ;
113
- }
119
+ $ tokens = $ file ->getTokens ();
120
+ $ lines = $ counted = [];
121
+ $ lastLine = null ;
122
+ for ($ i = $ start ; $ i < $ file ->numTokens ; $ i ++) {
123
+ if ($ tokens [$ i ]['line ' ] === $ lastLine ) {
124
+ $ lines [$ lastLine ] .= $ tokens [$ i ]['content ' ];
125
+ continue ;
126
+ }
114
127
115
- if ($ tokens [$ position ]['column ' ] !== 1
116
- && $ tokens [$ position ]['content ' ] === $ file ->eolChar
117
- ) {
118
- $ position --;
119
- }
128
+ if ($ lastLine && array_key_exists ($ lastLine , $ counted )) {
129
+ $ counted [$ lastLine ][0 ] = strlen (ltrim ($ lines [$ lastLine ]));
130
+ $ counted [$ lastLine ][2 ] = $ i - 1 ;
131
+ }
120
132
121
- $ length = $ tokens [$ position ]['column ' ] + $ tokens [$ position ]['length ' ] - 1 ;
133
+ $ lastLine = $ tokens [$ i ]['line ' ];
134
+ $ lines [$ lastLine ] = $ tokens [$ i ]['content ' ];
135
+ $ counted [$ lastLine ] = [0 , $ i , -1 ];
136
+ }
122
137
123
- if ($ length <= $ this ->lineLimit
124
- || $ this ->shouldIgnoreLine ($ tokens , $ file , $ position )
125
- ) {
126
- return ;
138
+ if ($ lastLine && array_key_exists ($ lastLine , $ counted ) && $ counted [$ lastLine ][2 ] === -1 ) {
139
+ $ counted [$ lastLine ][0 ] = strlen (ltrim ($ lines [$ lastLine ]));
140
+ $ counted [$ lastLine ][2 ] = $ i - 1 ;
127
141
}
128
142
129
- $ file -> addWarning (
130
- ' Line exceeds %s characters; contains %s characters ' ,
131
- $ position ,
132
- ' TooLong ' ,
133
- [ $ this -> lineLimit , $ length ]
143
+ return array_filter (
144
+ $ counted ,
145
+ function ( array $ line ): bool {
146
+ return $ line [ 0 ] > $ this -> lineLimit && $ line [ 1 ] > 0 && $ line [ 2 ] > 0 ;
147
+ }
134
148
);
135
149
}
136
150
137
151
/**
138
152
* Don't warn for lines that exceeds limit, but either are part of
139
- * translations function first argument or cointain single words that alone
153
+ * translations function first argument or contain single words that alone
140
154
* are longer that line limit (e.g. long URLs).
141
155
*
142
- * @param array $tokens
143
156
* @param File $file
144
- * @param int $position
157
+ * @param int $start
158
+ * @param int $end
145
159
* @return bool
146
160
*/
147
- private function shouldIgnoreLine (
148
- array $ tokens ,
149
- File $ file ,
150
- int $ position
151
- ): bool {
152
-
153
- $ line = $ tokens [$ position ]['line ' ];
154
- $ index = $ position ;
155
-
156
- while ($ index > 0 ) {
157
- if ($ this ->isI18nFunction ($ tokens , $ index , $ file )
158
- || $ this ->containLongWords ($ tokens , $ index )
159
- ) {
160
- return true ;
161
- }
162
- if ($ tokens [$ index ]['line ' ] !== $ line ) {
163
- break ;
164
- }
165
- $ index --;
166
- }
167
-
168
- return false ;
161
+ private function shouldIgnoreLine (File $ file , int $ start , int $ end ): bool
162
+ {
163
+ return
164
+ $ this ->containLongWords ($ file , $ start , $ end )
165
+ || $ this ->isI18nFunction ($ file , $ start , $ end );
169
166
}
170
167
171
168
/**
172
- * @param array $tokens
173
- * @param int $position
169
+ * @param File $file
170
+ * @param int $start
171
+ * @param int $end
174
172
* @return bool
175
173
*/
176
- private function containLongWords (
177
- array $ tokens ,
178
- int $ position
179
- ): bool {
180
-
181
- $ string = $ tokens [$ position ] ?? null ;
182
- if (!$ string
183
- || !in_array ($ string ['code ' ], self ::STRING_TYPES , true )
184
- || strlen ($ string ['content ' ]) < $ this ->lineLimit
185
- ) {
186
- return false ;
187
- }
174
+ private function containLongWords (File $ file , int $ start , int $ end ): bool
175
+ {
176
+ $ tokens = $ file ->getTokens ();
188
177
189
- $ words = array_filter (preg_split ('~[ ,.;:?!¿¡]~ ' , $ string ['content ' ]));
190
- foreach ($ words as $ word ) {
191
- if (strlen ($ word ) >= $ this ->lineLimit ) {
192
- return true ;
178
+ for ($ i = $ start ; $ i <= $ end ; $ i ++) {
179
+ if (!in_array ($ tokens [$ i ]['code ' ], self ::STRING_TYPES , true )) {
180
+ continue ;
193
181
}
182
+
183
+ $ words = array_filter (preg_split ('~[\s+]~ ' , $ tokens [$ i ]['content ' ]));
184
+ if (count ($ words ) > 2 ) {
185
+ return false ;
186
+ }
187
+
188
+ return (bool )array_filter (
189
+ array_map ('strlen ' , $ words ),
190
+ function (int $ len ): bool {
191
+ return ($ len + 3 ) > $ this ->lineLimit ;
192
+ }
193
+ );
194
194
}
195
195
196
196
return false ;
197
197
}
198
198
199
199
/**
200
- * @param array $tokens
201
- * @param int $position
202
200
* @param File $file
201
+ * @param int $start
202
+ * @param int $end
203
203
* @return bool
204
204
*/
205
- private function isI18nFunction (
206
- array $ tokens ,
207
- int $ position ,
208
- File $ file
209
- ): bool {
210
-
211
- $ string = $ tokens [$ position ] ?? null ;
212
- if (!$ string
213
- || $ string ['code ' ] !== T_CONSTANT_ENCAPSED_STRING
214
- || strlen ($ string ['content ' ]) < $ this ->lineLimit
215
- ) {
216
- return false ;
217
- }
205
+ private function isI18nFunction (File $ file , int $ start , int $ end ): bool
206
+ {
207
+ $ tokens = $ file ->getTokens ();
218
208
219
- $ previousPos = $ file ->findPrevious (
220
- self ::IGNORE_TYPES ,
221
- $ position - 1 ,
222
- null ,
223
- true ,
224
- null ,
225
- true
226
- );
209
+ for ($ i = $ start ; $ i <= $ end ; $ i ++) {
210
+ if ($ tokens [$ i ]['code ' ] !== T_CONSTANT_ENCAPSED_STRING
211
+ || (strlen ($ tokens [$ i ]['content ' ]) + 3 ) < $ this ->lineLimit
212
+ ) {
213
+ continue ;
214
+ }
227
215
228
- $ previous = $ previousPos ? $ tokens [$ previousPos ] ?? null : null ;
216
+ $ previousPos = $ file ->findPrevious (
217
+ self ::IGNORE_TYPES ,
218
+ $ i - 1 ,
219
+ null ,
220
+ true ,
221
+ null ,
222
+ true
223
+ );
224
+
225
+ $ previous = $ previousPos ? $ tokens [$ previousPos ] ?? null : null ;
226
+ if (!$ previous
227
+ || $ previous ['code ' ] !== T_STRING
228
+ || !in_array ($ previous ['content ' ], self ::I18N_FUNCTIONS , true )
229
+ ) {
230
+ continue ;
231
+ }
229
232
230
- if (!$ previous
231
- || $ previous ['code ' ] !== T_STRING
232
- || !in_array ($ previous ['content ' ], self ::I18N_FUNCTIONS , true )
233
- ) {
234
- return false ;
235
- }
233
+ $ next = $ file ->findNext (
234
+ [T_WHITESPACE ],
235
+ $ previousPos + 1 ,
236
+ null ,
237
+ true ,
238
+ null ,
239
+ true
240
+ );
236
241
237
- $ next = $ file ->findNext (
238
- [T_WHITESPACE ],
239
- $ previousPos + 1 ,
240
- null ,
241
- true ,
242
- null ,
243
- true
244
- );
242
+ if ($ tokens [$ next ]['code ' ] === T_OPEN_PARENTHESIS ) {
243
+ return true ;
244
+ }
245
+ }
245
246
246
- return $ tokens [ $ next ][ ' code ' ] === T_OPEN_PARENTHESIS ;
247
+ return false ;
247
248
}
248
249
}
0 commit comments