Skip to content

Commit d48aec1

Browse files
committed
PSR2R.WhiteSpace.ConsistentIndent
1 parent 8423411 commit d48aec1

File tree

2 files changed

+77
-39
lines changed

2 files changed

+77
-39
lines changed

PSR2R/Sniffs/WhiteSpace/ConsistentIndentSniff.php

Lines changed: 76 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,17 @@ public function process(File $phpcsFile, int $stackPtr): void {
7171
// Get the expected indentation based on scope
7272
$expectedIndent = $this->getExpectedIndent($phpcsFile, $nextToken, $tokens);
7373

74-
// Allow continuation lines (lines can be indented more for alignment)
75-
// But check if the previous line suggests this should NOT be indented more
74+
// Check if line is over-indented (more than expected for its scope)
7675
if ($currentIndent > $expectedIndent) {
76+
// Check if this line starts with a continuation operator
77+
if ($this->startsWithContinuationOperator($nextToken, $tokens)) {
78+
return; // Valid continuation line
79+
}
80+
7781
$prevLine = $this->findPreviousContentLine($phpcsFile, $stackPtr, $tokens);
78-
if ($prevLine !== null && $this->isOrphanedIndent($phpcsFile, $prevLine, $currentIndent, $expectedIndent, $tokens)) {
82+
83+
// Check if this is a valid continuation line or incorrectly indented
84+
if ($prevLine !== null && !$this->isValidContinuation($phpcsFile, $prevLine, $tokens)) {
7985
$error = 'Line indented incorrectly; expected %d tabs, found %d';
8086
$data = [$expectedIndent, $currentIndent];
8187
$fix = $phpcsFile->addFixableError($error, $stackPtr, 'Incorrect', $data);
@@ -146,48 +152,82 @@ protected function findPreviousContentLine(File $phpcsFile, int $stackPtr, array
146152
}
147153

148154
/**
149-
* Check if this looks like orphaned indentation (not a valid continuation).
155+
* Check if this line starts with a continuation operator.
156+
*
157+
* @param int $nextToken First non-whitespace token on the line
158+
* @param array $tokens
159+
*
160+
* @return bool
161+
*/
162+
protected function startsWithContinuationOperator(int $nextToken, array $tokens): bool {
163+
$continuationStarters = [
164+
\T_STRING_CONCAT,
165+
\T_OBJECT_OPERATOR,
166+
\T_NULLSAFE_OBJECT_OPERATOR,
167+
\T_BOOLEAN_AND,
168+
\T_BOOLEAN_OR,
169+
\T_LOGICAL_AND,
170+
\T_LOGICAL_OR,
171+
\T_PLUS,
172+
\T_MINUS,
173+
\T_MULTIPLY,
174+
\T_DIVIDE,
175+
];
176+
177+
return in_array($tokens[$nextToken]['code'], $continuationStarters, true);
178+
}
179+
180+
/**
181+
* Check if this looks like a valid continuation line (allowed to have extra indentation).
150182
*
151183
* @param \PHP_CodeSniffer\Files\File $phpcsFile
152184
* @param int $prevToken Previous content token
153-
* @param int $currentIndent
154-
* @param int $expectedIndent
155185
* @param array $tokens
156186
*
157-
* @return bool
187+
* @return bool True if this is a valid continuation, false if it should match scope indent
158188
*/
159-
protected function isOrphanedIndent(File $phpcsFile, int $prevToken, int $currentIndent, int $expectedIndent, array $tokens): bool {
160-
// Pattern 1: Previous line was a closing brace
161-
// This catches: } \n orphaned code
162-
if ($tokens[$prevToken]['code'] === T_CLOSE_CURLY_BRACKET) {
189+
protected function isValidContinuation(File $phpcsFile, int $prevToken, array $tokens): bool {
190+
$prevCode = $tokens[$prevToken]['code'];
191+
192+
// Tokens that indicate the next line is a continuation
193+
$continuationTokens = [
194+
\T_PLUS,
195+
\T_MINUS,
196+
\T_MULTIPLY,
197+
\T_DIVIDE,
198+
\T_MODULUS,
199+
\T_STRING_CONCAT,
200+
\T_COMMA,
201+
\T_OPEN_PARENTHESIS,
202+
\T_OPEN_SQUARE_BRACKET,
203+
\T_OPEN_SHORT_ARRAY,
204+
\T_DOUBLE_ARROW,
205+
\T_BOOLEAN_AND,
206+
\T_BOOLEAN_OR,
207+
\T_LOGICAL_AND,
208+
\T_LOGICAL_OR,
209+
\T_INSTANCEOF,
210+
\T_INLINE_THEN,
211+
\T_COALESCE,
212+
\T_OBJECT_OPERATOR,
213+
\T_NULLSAFE_OBJECT_OPERATOR,
214+
\T_EQUAL,
215+
\T_PLUS_EQUAL,
216+
\T_MINUS_EQUAL,
217+
\T_MUL_EQUAL,
218+
\T_DIV_EQUAL,
219+
\T_CONCAT_EQUAL,
220+
\T_MOD_EQUAL,
221+
];
222+
223+
if (in_array($prevCode, $continuationTokens, true)) {
163224
return true;
164225
}
165226

166-
// Pattern 2: Previous line ended with }; (closure, array, etc.)
167-
// This catches: }; \n orphaned code
168-
if ($tokens[$prevToken]['code'] === T_SEMICOLON) {
169-
// Check if the token before semicolon is a closing brace
170-
$beforeSemicolon = $phpcsFile->findPrevious(T_WHITESPACE, $prevToken - 1, null, true);
171-
if ($beforeSemicolon !== false && $tokens[$beforeSemicolon]['code'] === T_CLOSE_CURLY_BRACKET) {
172-
return true;
173-
}
174-
175-
// Pattern 3: Previous line is at the same over-indented level
176-
// This catches consecutive orphaned lines: } \n line1; \n line2;
177-
// Find the start of the previous line to check its indentation
178-
$prevLineStart = $prevToken;
179-
while ($prevLineStart > 0 && $tokens[$prevLineStart - 1]['line'] === $tokens[$prevToken]['line']) {
180-
$prevLineStart--;
181-
}
182-
183-
// Check if previous line started with whitespace
184-
if ($tokens[$prevLineStart]['code'] === T_WHITESPACE) {
185-
$prevIndent = $this->getIndentLevel($tokens[$prevLineStart]);
186-
// If previous line was also over-indented at the same level, this is likely orphaned too
187-
if ($prevIndent === $currentIndent && $prevIndent > $expectedIndent) {
188-
return true;
189-
}
190-
}
227+
// Check string representation for bracket tokens (PHPCS sometimes uses string codes)
228+
$prevContent = $tokens[$prevToken]['content'] ?? '';
229+
if ($prevContent === '[' || $prevContent === '(') {
230+
return true;
191231
}
192232

193233
return false;

PSR2R/Sniffs/WhiteSpace/TabIndentSniff.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,7 @@ public function process(File $phpcsFile, int $stackPtr): void {
4646
for ($i = $stackPtr + 1; $i < $tokens[$stackPtr]['comment_closer']; $i++) {
4747
if ($tokens[$i]['code'] === 'PHPCS_T_DOC_COMMENT_WHITESPACE' && $tokens[$i]['column'] === 1) {
4848
$this->fixTab($phpcsFile, $i, $tokens);
49-
} /** @noinspection NotOptimalIfConditionsInspection */ elseif ($tokens[$i]['code'] ===
50-
'PHPCS_T_DOC_COMMENT_WHITESPACE'
51-
) {
49+
} elseif ($tokens[$i]['code'] === 'PHPCS_T_DOC_COMMENT_WHITESPACE') {
5250
$this->fixSpace($phpcsFile, $i, $tokens);
5351
}
5452
}

0 commit comments

Comments
 (0)