@@ -102,8 +102,7 @@ private function validateMultilineEmbeddedPhp($phpcsFile, $stackPtr, $closingTag
102
102
$ error = 'Opening PHP tag must be on a line by itself ' ;
103
103
$ fix = $ phpcsFile ->addFixableError ($ error , $ stackPtr , 'ContentAfterOpen ' );
104
104
if ($ fix === true ) {
105
- $ first = $ phpcsFile ->findFirstOnLine (T_WHITESPACE , $ stackPtr , true );
106
- $ padding = (strlen ($ tokens [$ first ]['content ' ]) - strlen (ltrim ($ tokens [$ first ]['content ' ])));
105
+ $ padding = $ this ->calculateLineIndent ($ phpcsFile , $ stackPtr );
107
106
108
107
$ phpcsFile ->fixer ->beginChangeset ();
109
108
$ phpcsFile ->fixer ->replaceToken ($ stackPtr , rtrim ($ tokens [$ stackPtr ]['content ' ]));
@@ -147,17 +146,7 @@ private function validateMultilineEmbeddedPhp($phpcsFile, $stackPtr, $closingTag
147
146
}
148
147
}//end if
149
148
150
- $ indent = 0 ;
151
- $ first = $ phpcsFile ->findFirstOnLine (T_WHITESPACE , $ stackPtr );
152
- if ($ first === false ) {
153
- $ first = $ phpcsFile ->findFirstOnLine (T_INLINE_HTML , $ stackPtr );
154
- if ($ first !== false ) {
155
- $ indent = (strlen ($ tokens [$ first ]['content ' ]) - strlen (ltrim ($ tokens [$ first ]['content ' ])));
156
- }
157
- } else {
158
- $ indent = ($ tokens [($ first + 1 )]['column ' ] - 1 );
159
- }
160
-
149
+ $ indent = $ this ->calculateLineIndent ($ phpcsFile , $ stackPtr );
161
150
$ contentColumn = ($ tokens [$ firstContent ]['column ' ] - 1 );
162
151
if ($ contentColumn !== $ indent ) {
163
152
$ error = 'First line of embedded PHP code must be indented %s spaces; %s found ' ;
@@ -180,52 +169,40 @@ private function validateMultilineEmbeddedPhp($phpcsFile, $stackPtr, $closingTag
180
169
181
170
$ lastContentBeforeBlock = $ phpcsFile ->findPrevious (T_WHITESPACE , ($ stackPtr - 1 ), null , true );
182
171
if ($ tokens [$ lastContentBeforeBlock ]['line ' ] === $ tokens [$ stackPtr ]['line ' ]
183
- && trim ($ tokens [$ lastContentBeforeBlock ]['content ' ]) !== ''
172
+ && (($ tokens [$ lastContentBeforeBlock ]['code ' ] === T_INLINE_HTML
173
+ && trim ($ tokens [$ lastContentBeforeBlock ]['content ' ]) !== '' )
174
+ || ($ tokens [($ lastContentBeforeBlock - 1 )]['code ' ] !== T_INLINE_HTML
175
+ && $ tokens [($ lastContentBeforeBlock - 1 )]['line ' ] === $ tokens [$ stackPtr ]['line ' ]))
184
176
) {
185
177
$ error = 'Opening PHP tag must be on a line by itself ' ;
186
178
$ fix = $ phpcsFile ->addFixableError ($ error , $ stackPtr , 'ContentBeforeOpen ' );
187
179
if ($ fix === true ) {
188
- $ padding = 0 ;
189
- $ first = $ phpcsFile ->findFirstOnLine (T_WHITESPACE , $ stackPtr );
190
- if ($ first === false ) {
191
- $ first = $ phpcsFile ->findFirstOnLine (T_INLINE_HTML , $ stackPtr );
192
- if ($ first !== false ) {
193
- $ padding = (strlen ($ tokens [$ first ]['content ' ]) - strlen (ltrim ($ tokens [$ first ]['content ' ])));
194
- }
195
- } else {
196
- $ padding = ($ tokens [($ first + 1 )]['column ' ] - 1 );
197
- }
180
+ $ padding = $ this ->calculateLineIndent ($ phpcsFile , $ lastContentBeforeBlock );
198
181
182
+ $ phpcsFile ->fixer ->beginChangeset ();
199
183
$ phpcsFile ->fixer ->addContentBefore ($ stackPtr , $ phpcsFile ->eolChar .str_repeat (' ' , $ padding ));
200
- }
184
+
185
+ // Make sure we don't leave trailing whitespace behind.
186
+ if ($ tokens [($ stackPtr - 1 )]['code ' ] === T_INLINE_HTML
187
+ && trim ($ tokens [($ stackPtr - 1 )]['content ' ]) === ''
188
+ ) {
189
+ $ phpcsFile ->fixer ->replaceToken (($ stackPtr - 1 ), '' );
190
+ }
191
+
192
+ $ phpcsFile ->fixer ->endChangeset ();
193
+ }//end if
201
194
} else {
202
195
// Find the first token on the first non-empty line we find.
203
196
for ($ first = ($ lastContentBeforeBlock - 1 ); $ first > 0 ; $ first --) {
204
197
if ($ tokens [$ first ]['line ' ] === $ tokens [$ stackPtr ]['line ' ]) {
205
198
continue ;
206
199
} else if (trim ($ tokens [$ first ]['content ' ]) !== '' ) {
207
200
$ first = $ phpcsFile ->findFirstOnLine ([], $ first , true );
208
- if ($ tokens [$ first ]['code ' ] === T_COMMENT
209
- && $ tokens [$ first ]['content ' ] !== ltrim ($ tokens [$ first ]['content ' ])
210
- ) {
211
- // This is a subsequent line in a star-slash comment containing leading indent.
212
- // We'll need the first line of the comment to correctly determine the indent.
213
- continue ;
214
- }
215
-
216
201
break ;
217
202
}
218
203
}
219
204
220
- $ expected = 0 ;
221
- if ($ tokens [$ first ]['code ' ] === T_INLINE_HTML
222
- && trim ($ tokens [$ first ]['content ' ]) !== ''
223
- ) {
224
- $ expected = (strlen ($ tokens [$ first ]['content ' ]) - strlen (ltrim ($ tokens [$ first ]['content ' ])));
225
- } else if ($ tokens [$ first ]['code ' ] === T_WHITESPACE ) {
226
- $ expected = ($ tokens [($ first + 1 )]['column ' ] - 1 );
227
- }
228
-
205
+ $ expected = $ this ->calculateLineIndent ($ phpcsFile , $ first );
229
206
$ expected += 4 ;
230
207
$ found = ($ tokens [$ stackPtr ]['column ' ] - 1 );
231
208
if ($ found > $ expected ) {
@@ -261,17 +238,7 @@ private function validateMultilineEmbeddedPhp($phpcsFile, $stackPtr, $closingTag
261
238
) {
262
239
$ closerIndent = $ indent ;
263
240
} else {
264
- $ first = $ phpcsFile ->findFirstOnLine (T_WHITESPACE , $ closingTag , true );
265
-
266
- while ($ tokens [$ first ]['code ' ] === T_COMMENT
267
- && $ tokens [$ first ]['content ' ] !== ltrim ($ tokens [$ first ]['content ' ])
268
- ) {
269
- // This is a subsequent line in a star-slash comment containing leading indent.
270
- // We'll need the first line of the comment to correctly determine the indent.
271
- $ first = $ phpcsFile ->findFirstOnLine (T_WHITESPACE , ($ first - 1 ), true );
272
- }
273
-
274
- $ closerIndent = ($ tokens [$ first ]['column ' ] - 1 );
241
+ $ closerIndent = $ this ->calculateLineIndent ($ phpcsFile , $ closingTag );
275
242
}
276
243
277
244
$ phpcsFile ->fixer ->beginChangeset ();
@@ -290,10 +257,10 @@ private function validateMultilineEmbeddedPhp($phpcsFile, $stackPtr, $closingTag
290
257
$ error = 'Closing PHP tag must be on a line by itself ' ;
291
258
$ fix = $ phpcsFile ->addFixableError ($ error , $ closingTag , 'ContentAfterEnd ' );
292
259
if ($ fix === true ) {
293
- $ first = $ phpcsFile -> findFirstOnLine ( T_WHITESPACE , $ closingTag, true );
260
+ $ indent = $ this -> calculateLineIndent ( $ phpcsFile , $ closingTag );
294
261
$ phpcsFile ->fixer ->beginChangeset ();
295
262
$ phpcsFile ->fixer ->addNewline ($ closingTag );
296
- $ phpcsFile ->fixer ->addContent ($ closingTag , str_repeat (' ' , ( $ tokens [ $ first ][ ' column ' ] - 1 ) ));
263
+ $ phpcsFile ->fixer ->addContent ($ closingTag , str_repeat (' ' , $ indent ));
297
264
298
265
if ($ tokens [$ firstContentAfterBlock ]['code ' ] === T_INLINE_HTML ) {
299
266
$ trimmedHtmlContent = ltrim ($ tokens [$ firstContentAfterBlock ]['content ' ]);
@@ -513,4 +480,44 @@ private function reportEmptyTagSet(File $phpcsFile, $stackPtr, $closeTag)
513
480
}//end reportEmptyTagSet()
514
481
515
482
483
+ /**
484
+ * Calculate the indent of the line containing the stackPtr.
485
+ *
486
+ * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
487
+ * @param int $stackPtr The position of the current token in the
488
+ * stack passed in $tokens.
489
+ *
490
+ * @return int
491
+ */
492
+ private function calculateLineIndent (File $ phpcsFile , $ stackPtr )
493
+ {
494
+ $ tokens = $ phpcsFile ->getTokens ();
495
+
496
+ for ($ firstOnLine = $ stackPtr ; $ tokens [$ firstOnLine ]['column ' ] !== 1 ; $ firstOnLine --);
497
+
498
+ // Check if this is a subsequent line in a star-slash comment containing leading indent.
499
+ // In that case, we'll need the first line of the comment to correctly determine the indent.
500
+ while ($ tokens [$ firstOnLine ]['code ' ] === T_COMMENT
501
+ && $ tokens [$ firstOnLine ]['content ' ] !== ltrim ($ tokens [$ firstOnLine ]['content ' ])
502
+ ) {
503
+ for (--$ firstOnLine ; $ tokens [$ firstOnLine ]['column ' ] !== 1 ; $ firstOnLine --);
504
+ }
505
+
506
+ $ indent = 0 ;
507
+ if ($ tokens [$ firstOnLine ]['code ' ] === T_WHITESPACE ) {
508
+ $ indent = ($ tokens [($ firstOnLine + 1 )]['column ' ] - 1 );
509
+ } else if ($ tokens [$ firstOnLine ]['code ' ] === T_INLINE_HTML
510
+ || $ tokens [$ firstOnLine ]['code ' ] === T_END_HEREDOC
511
+ || $ tokens [$ firstOnLine ]['code ' ] === T_END_NOWDOC
512
+ ) {
513
+ $ indent = (strlen ($ tokens [$ firstOnLine ]['content ' ]) - strlen (ltrim ($ tokens [$ firstOnLine ]['content ' ])));
514
+ } else if ($ tokens [$ firstOnLine ]['code ' ] === T_DOC_COMMENT_WHITESPACE ) {
515
+ $ indent = (strlen ($ tokens [$ firstOnLine ]['content ' ]) - strlen (ltrim ($ tokens [$ firstOnLine ]['content ' ])) - 1 );
516
+ }
517
+
518
+ return $ indent ;
519
+
520
+ }//end calculateLineIndent()
521
+
522
+
516
523
}//end class
0 commit comments