Skip to content

Commit

Permalink
bug: Fix various indentation issues (#6480)
Browse files Browse the repository at this point in the history
Fix various indentation issues
  • Loading branch information
julienfalque authored Jul 15, 2022
1 parent f403e7f commit 54d2c6f
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 34 deletions.
63 changes: 30 additions & 33 deletions src/Fixer/Whitespace/StatementIndentationFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
[
'type' => 'block',
'end_index' => $endIndex,
'end_index_inclusive' => true,
'initial_indent' => $lastIndent,
'is_indented_block' => false,
],
Expand All @@ -149,13 +150,15 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
|| isset($alternativeBlockStarts[$index])
|| isset($caseBlockStarts[$index])
) {
$endIndexInclusive = true;

if ($token->isGivenKind([T_EXTENDS, T_IMPLEMENTS])) {
$endIndex = $tokens->getNextTokenOfKind($index, ['{']);
} elseif ($token->isGivenKind(CT::T_USE_TRAIT)) {
$endIndex = $tokens->getNextTokenOfKind($index, [';']);
} elseif ($token->equals(':')) {
if (isset($caseBlockStarts[$index])) {
$endIndex = $this->findCaseBlockEnd($tokens, $index);
[$endIndex, $endIndexInclusive] = $this->findCaseBlockEnd($tokens, $index);
} else {
$endIndex = $this->alternativeSyntaxAnalyzer->findAlternativeSyntaxBlockEnd($tokens, $alternativeBlockStarts[$index]);
}
Expand All @@ -180,6 +183,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
$scopes[] = [
'type' => 'block',
'end_index' => $endIndex,
'end_index_inclusive' => $endIndexInclusive,
'initial_indent' => $initialIndent,
'is_indented_block' => true,
];
Expand Down Expand Up @@ -213,6 +217,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
$scopes[] = [
'type' => 'block_signature',
'end_index' => $endIndex,
'end_index_inclusive' => true,
'initial_indent' => $this->getLineIndentationWithBracesCompatibility($tokens, $index, $lastIndent),
'is_indented_block' => false,
];
Expand Down Expand Up @@ -270,35 +275,18 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
}
}

$isIndentableStatement = !$this->isCommentForControlSructureContinuation($tokens, $index + 1);

if (
$isIndentableStatement
&& (
(null !== $firstMeaningFulTokenIndex && $firstMeaningFulTokenIndex < $scopes[$currentScope]['end_index'])
|| (null !== $nextNewlineIndex && $nextNewlineIndex < $scopes[$currentScope]['end_index'])
)
) {
$indent = true;
} elseif (null !== $nextNewlineIndex) {
for ($parentScope = $currentScope - 1; $parentScope >= 0; --$parentScope) {
if ($scopes[$parentScope]['end_index'] < $nextNewlineIndex) {
continue;
}

if (!isset($scopes[$parentScope]['is_indented_block']) || !$scopes[$parentScope]['is_indented_block']) {
break;
}
if (!$this->isCommentForControlSructureContinuation($tokens, $index + 1)) {
$endIndex = $scopes[$currentScope]['end_index'];

if (
$isIndentableStatement
&& $firstMeaningFulTokenIndex < $scopes[$parentScope]['end_index']
&& \strlen($scopes[$parentScope]['initial_indent']) >= \strlen($scopes[$currentScope]['initial_indent'])
) {
$indent = true;
}
if (!$scopes[$currentScope]['end_index_inclusive']) {
++$endIndex;
}

break;
if (
(null !== $firstMeaningFulTokenIndex && $firstMeaningFulTokenIndex < $endIndex)
|| (null !== $nextNewlineIndex && $nextNewlineIndex < $endIndex)
) {
$indent = true;
}
}
}
Expand Down Expand Up @@ -376,6 +364,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
$scopes[] = [
'type' => 'statement',
'end_index' => $endIndex,
'end_index_inclusive' => false,
'initial_indent' => $previousLineInitialIndent,
'new_indent' => $previousLineNewIndent,
];
Expand All @@ -387,7 +376,7 @@ private function findStatementEndIndex(Tokens $tokens, int $index, int $parentSc
{
$endIndex = null;

for ($searchEndIndex = $index; $searchEndIndex < $parentScopeEndIndex; ++$searchEndIndex) {
for ($searchEndIndex = $index; $searchEndIndex <= $parentScopeEndIndex; ++$searchEndIndex) {
$searchEndToken = $tokens[$searchEndIndex];

if ($searchEndToken->equalsAny(['(', '{', [CT::T_ARRAY_SQUARE_BRACE_OPEN]])) {
Expand All @@ -405,7 +394,7 @@ private function findStatementEndIndex(Tokens $tokens, int $index, int $parentSc
}

if ($searchEndToken->equalsAny([';', ',', '}', [T_CLOSE_TAG]])) {
$endIndex = $tokens->getPrevMeaningfulToken($searchEndIndex);
$endIndex = $tokens->getPrevNonWhitespace($searchEndIndex);

break;
}
Expand All @@ -414,7 +403,10 @@ private function findStatementEndIndex(Tokens $tokens, int $index, int $parentSc
return $endIndex ?? $tokens->getPrevMeaningfulToken($parentScopeEndIndex);
}

private function findCaseBlockEnd(Tokens $tokens, int $index): int
/**
* @return array{int, bool}
*/
private function findCaseBlockEnd(Tokens $tokens, int $index): array
{
for ($max = \count($tokens); $index < $max; ++$index) {
if ($tokens[$index]->isGivenKind(T_SWITCH)) {
Expand All @@ -441,11 +433,11 @@ private function findCaseBlockEnd(Tokens $tokens, int $index): int
}

if ($tokens[$index]->equalsAny([[T_CASE], [T_DEFAULT]])) {
return $index;
return [$index, true];
}

if ($tokens[$index]->equalsAny(['}', [T_ENDSWITCH]])) {
return $tokens->getPrevMeaningfulToken($index);
return [$tokens->getPrevMeaningfulToken($index), false];
}
}

Expand Down Expand Up @@ -482,6 +474,11 @@ private function isCommentForControlSructureContinuation(Tokens $tokens, int $in
return false;
}

$prevIndex = $tokens->getPrevMeaningfulToken($index);
if (null !== $prevIndex && $tokens[$prevIndex]->equals('{')) {
return false;
}

$index = $tokens->getNextMeaningfulToken($index + 1);

if (null === $index || !$tokens[$index]->equals('}')) {
Expand Down
50 changes: 49 additions & 1 deletion tests/Fixer/Whitespace/StatementIndentationFixerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,14 @@ public function provideFixCases(): iterable
foo();',
];

// @TODO brace at line 6 should have one level of indentation
yield 'with several opening braces on same line' => [
'<?php
if ($foo) { if ($foo) { foo();
if ($bar) { if ($bar) { bar(); }
baz();
}
}
}
baz();
}
baz();',
Expand Down Expand Up @@ -641,6 +642,53 @@ public function foo(
bar();
}
return true;
}',
];

yield 'comment in method calls chain' => [
'<?php
$foo
->baz()
/* ->baz() */
;',
];

yield 'if with only a comment and followed by else' => [
'<?php
if (true) {
// foo
} else {
// bar
}',
];

yield 'multiple anonymous functions as function arguments' => [
'<?php
foo(function () {
bar();
}, function () {
baz();
});',
];

yield 'multiple anonymous functions as method arguments' => [
'<?php
$this
->bar(function ($a) {
echo $a;
}, function ($b) {
echo $b;
})
;',
];

yield 'semicolon on a newline inside a switch case without break statement' => [
'<?php
switch (true) {
case $foo:
$foo
->baz()
;
}',
];
}
Expand Down

0 comments on commit 54d2c6f

Please sign in to comment.