Skip to content

Commit 481d003

Browse files
committed
PSR2R.WhiteSpace.ConsistentIndent
1 parent 4fca9a9 commit 481d003

File tree

3 files changed

+135
-4
lines changed

3 files changed

+135
-4
lines changed

PSR2R/Sniffs/WhiteSpace/ConsistentIndentSniff.php

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ public function process(File $phpcsFile, int $stackPtr): void {
5757
return;
5858
}
5959

60+
// Skip comments - they should maintain their context's indentation
61+
if ($tokens[$nextToken]['code'] === T_COMMENT || $tokens[$nextToken]['code'] === T_DOC_COMMENT_OPEN_TAG) {
62+
return;
63+
}
64+
6065
// Skip closing braces - they're allowed to be dedented
6166
if ($tokens[$nextToken]['code'] === T_CLOSE_CURLY_BRACKET) {
6267
return;
@@ -70,11 +75,12 @@ public function process(File $phpcsFile, int $stackPtr): void {
7075
// Get the expected indentation based on scope
7176
$expectedIndent = $this->getExpectedIndent($phpcsFile, $nextToken, $tokens);
7277

73-
// Special handling for break/continue in switch statements
78+
// Special handling for control flow keywords in switch statements
7479
// They can be indented one level deeper (at case body level)
75-
if (in_array($tokens[$nextToken]['code'], [T_BREAK, T_CONTINUE], true)) {
80+
$switchControlFlowTokens = [T_BREAK, T_CONTINUE, T_RETURN, T_THROW];
81+
if (in_array($tokens[$nextToken]['code'], $switchControlFlowTokens, true)) {
7682
if ($this->isInSwitch($tokens, $nextToken)) {
77-
// Allow one extra level of indentation for break/continue in switch
83+
// Allow one extra level of indentation in switch
7884
// (they're typically at the same level as case body code)
7985
if ($currentIndent === $expectedIndent + 1) {
8086
return;
@@ -235,6 +241,8 @@ protected function startsWithContinuationOperator(int $nextToken, array $tokens)
235241
\T_MINUS,
236242
\T_MULTIPLY,
237243
\T_DIVIDE,
244+
\T_INLINE_THEN, // Ternary ?
245+
\T_INLINE_ELSE, // Ternary :
238246
];
239247

240248
return in_array($tokens[$nextToken]['code'], $continuationStarters, true);
@@ -270,7 +278,8 @@ protected function isValidContinuation(File $phpcsFile, int $prevToken, array $t
270278
\T_LOGICAL_AND,
271279
\T_LOGICAL_OR,
272280
\T_INSTANCEOF,
273-
\T_INLINE_THEN,
281+
\T_INLINE_THEN, // Ternary ?
282+
\T_INLINE_ELSE, // Ternary :
274283
\T_COALESCE,
275284
\T_OBJECT_OPERATOR,
276285
\T_NULLSAFE_OBJECT_OPERATOR,
@@ -281,6 +290,13 @@ protected function isValidContinuation(File $phpcsFile, int $prevToken, array $t
281290
\T_DIV_EQUAL,
282291
\T_CONCAT_EQUAL,
283292
\T_MOD_EQUAL,
293+
\T_IS_EQUAL, // ==
294+
\T_IS_NOT_EQUAL, // !=
295+
\T_IS_IDENTICAL, // ===
296+
\T_IS_NOT_IDENTICAL, // !==
297+
\T_IS_SMALLER_OR_EQUAL, // <=
298+
\T_IS_GREATER_OR_EQUAL, // >=
299+
\T_SPACESHIP, // <=>
284300
];
285301

286302
if (in_array($prevCode, $continuationTokens, true)) {
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?php
2+
3+
/**
4+
* MIT License
5+
* For full license information, please view the LICENSE file that was distributed with this source code.
6+
*/
7+
8+
namespace PSR2R\Test\PSR2R\Sniffs\WhiteSpace;
9+
10+
use PSR2R\Sniffs\WhiteSpace\ConsistentIndentSniff;
11+
use PSR2R\Test\TestCase;
12+
13+
/**
14+
* Tests that ConsistentIndentSniff does not flag valid control flow patterns.
15+
*/
16+
class ConsistentIndentControlFlowNoErrorsSniffTest extends TestCase {
17+
18+
/**
19+
* Test that valid control flow patterns are not flagged.
20+
*
21+
* @return void
22+
*/
23+
public function testConsistentIndentControlFlowNoErrors(): void {
24+
$this->assertSnifferFindsErrors(new ConsistentIndentSniff(), 0);
25+
}
26+
27+
/**
28+
* Test that no changes are made to valid code.
29+
*
30+
* @return void
31+
*/
32+
public function testConsistentIndentControlFlowNoErrorsFixer(): void {
33+
$this->assertSnifferCanFixErrors(new ConsistentIndentSniff(), 0);
34+
}
35+
36+
/**
37+
* @return string
38+
*/
39+
protected function testFilePath(): string {
40+
return implode(DIRECTORY_SEPARATOR, [
41+
__DIR__,
42+
'..', '..', '..', '_data',
43+
]) . DIRECTORY_SEPARATOR;
44+
}
45+
46+
/**
47+
* @param \PHP_CodeSniffer\Sniffs\Sniff $sniffer
48+
*
49+
* @return string
50+
*/
51+
protected function getDummyFileBefore($sniffer): string {
52+
$className = 'ConsistentIndentControlFlowNoErrors';
53+
54+
$file = $this->testFilePath() . $className . DIRECTORY_SEPARATOR . static::FILE_BEFORE;
55+
if (!file_exists($file)) {
56+
$this->fail(sprintf('File not found: %s.', $file));
57+
}
58+
59+
return $file;
60+
}
61+
62+
/**
63+
* @param \PHP_CodeSniffer\Sniffs\Sniff $sniffer
64+
*
65+
* @return string
66+
*/
67+
protected function getDummyFileAfter($sniffer): string {
68+
$className = 'ConsistentIndentControlFlowNoErrors';
69+
70+
$file = $this->testFilePath() . $className . DIRECTORY_SEPARATOR . static::FILE_AFTER;
71+
if (!file_exists($file)) {
72+
$this->fail(sprintf('File not found: %s.', $file));
73+
}
74+
75+
return $file;
76+
}
77+
78+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
/**
4+
* MIT License
5+
* For full license information, please view the LICENSE file that was distributed with this source code.
6+
*/
7+
8+
namespace PSR2R\Test\PSR2R\Sniffs\WhiteSpace;
9+
10+
use PSR2R\Sniffs\WhiteSpace\ConsistentIndentSniff;
11+
use PSR2R\Test\TestCase;
12+
13+
/**
14+
* Tests for ConsistentIndentSniff with control flow keywords (return, break, continue, throw).
15+
*/
16+
class ConsistentIndentControlFlowSniffTest extends TestCase {
17+
18+
/**
19+
* Test that the sniffer finds orphaned control flow statements.
20+
*
21+
* @return void
22+
*/
23+
public function testConsistentIndentControlFlowSniffer(): void {
24+
$errors = $this->runFixer(new ConsistentIndentSniff());
25+
$this->assertGreaterThan(0, count($errors), 'Should find at least one error');
26+
}
27+
28+
/**
29+
* Test that the fixer can fix orphaned control flow statements.
30+
*
31+
* @return void
32+
*/
33+
public function testConsistentIndentControlFlowFixer(): void {
34+
$this->assertSnifferCanFixErrors(new ConsistentIndentSniff());
35+
}
36+
37+
}

0 commit comments

Comments
 (0)