PHP-CS-Fixer: wrong indentation after comment in if statement

All leading whitespaces are tabs. Fixer is run with psr2 level. As a result echo ‘1’; is not indented properly. If I run fixer with config (listed below) then tab in echo line is not converted and line is not properly indented.

Also fixer doesn’t cut to minimum indentation level although I’m not sure if this is a bug or intended behaviour.

.php_cs

<?php

return Symfony\CS\Config\Config::create()
    ->setUsingCache(true)
    ->level(Symfony\CS\FixerInterface::NONE_LEVEL)
    ->fixers(array(
        'encoding',
        'short_tag',
        'braces',
        'eof_ending',
        'linefeed',
        'parenthesis',
        'php_closing_tag',
        'whitespacy_lines',
        'trailing_spaces',
        'indentation'
    ))
;

test.php

<?php

    if (false) {
    // line after comment is not indented properly
    echo '1';

        $id = 10;
    }

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Reactions: 1
  • Comments: 16 (8 by maintainers)

Commits related to this issue

Most upvoted comments

It works with small files but it does not work with longer files I tested (statements are still not indented after line comments). I will investigate this problem further.

Unit tests passed with these changes

OK, but incomplete, skipped, or risky tests! Tests: 5412, Assertions: 111016, Skipped: 34.

diff --git a/src/Fixer/Basic/BracesFixer.php b/src/Fixer/Basic/BracesFixer.php
index 1cc8ce1..5afc9a5 100644
--- a/src/Fixer/Basic/BracesFixer.php
+++ b/src/Fixer/Basic/BracesFixer.php
@@ -229,13 +229,28 @@ function ($item) {
                     continue;
                 }

-                if (1 === $nestLevel && $nestToken->equalsAny(array(';', '}'))) {
+                $isNewLine = function($index, $direction) use ($tokens) {
+                    $index = $tokens->getTokenOfKindSibling($index, $direction, array(array(T_WHITESPACE)));
+                    if ($index !== null) {
+                        $token = $tokens[$index];
+                        return strpos($token->getContent(), "\n") !== false;
+                    }
+                    return false;
+                };
+
+                if (1 === $nestLevel && ($nestToken->equalsAny(array(';', '}')) || $nestToken->isComment())) { // indent after comment
                     $nextNonWhitespaceNestIndex = $tokens->getNextNonWhitespace($nestIndex);
                     $nextNonWhitespaceNestToken = $tokens[$nextNonWhitespaceNestIndex];
+                    $prevNonWhitespaceNestIndex = $tokens->getPrevNonWhitespace($nestIndex);
+                    $prevNonWhitespaceNestToken = $tokens[$prevNonWhitespaceNestIndex];
+                    $isNextWhitespaceNewline = $isNewLine($nestIndex, 1);

                     if (
-                        // next Token is not a comment
-                        !$nextNonWhitespaceNestToken->isComment() &&
+                        // next token is not a comment or it is not a comment in the same line as the opening brace or a comment before a control statement
+                        (!$nestToken->isComment() || !($prevNonWhitespaceNestToken->equals('{') || $nextNonWhitespaceNestToken->isGivenKind($indentTokens))) &&
+                        // next Token is not a comment or the comment is on another line
+                        (!$nextNonWhitespaceNestToken->isComment() || $isNextWhitespaceNewline) &&
+                        // !$nextNonWhitespaceNestToken->isComment() &&
                         // and it is not a `$foo = function () {};` situation
                         !($nestToken->equals('}') && $nextNonWhitespaceNestToken->equalsAny(array(';', ',', ']', array(CT::T_ARRAY_SQUARE_BRACE_CLOSE)))) &&
                         // and it is not a `Foo::{bar}()` situation