Skip to content

Generic/OpeningFunctionBraceBsdAllman: potential minor bug when fixing the BraceOnSameLine error #1145

Open
@rodrigoprimo

Description

@rodrigoprimo

Describe the bug

The Generic.Functions.OpeningFunctionBraceBsdAllman sniff doesn't take into consideration the indentation of the function declaration when moving the opening brace to a new line (BraceOnSameLine error). I'm inclined to think it should, but I'm not sure. Regardless of that, there seems to be code to take into consideration the indentation, but this code doesn't work, or I'm misunderstanding how it is supposed to work:

$indent = $phpcsFile->findFirstOnLine([], $openingBrace);
if ($hasTrailingAnnotation === false || $nextLine === false) {
if ($tokens[$indent]['code'] === T_WHITESPACE) {
$phpcsFile->fixer->addContentBefore($openingBrace, $tokens[$indent]['content']);
}
if ($tokens[($openingBrace - 1)]['code'] === T_WHITESPACE) {
$phpcsFile->fixer->replaceToken(($openingBrace - 1), '');
}
$phpcsFile->fixer->addNewlineBefore($openingBrace);
} else {
$phpcsFile->fixer->replaceToken($openingBrace, '');
$phpcsFile->fixer->addNewlineBefore($nextLine);
$phpcsFile->fixer->addContentBefore($nextLine, '{');
if ($tokens[$indent]['code'] === T_WHITESPACE) {
$phpcsFile->fixer->addContentBefore($nextLine, $tokens[$indent]['content']);
}
}

It seems to me that since an empty array is passed to findFirstOnLine(), $indent will always be false and thus the content of $tokens[$indent] is never added before the opening brace on lines 117 and 131.

This is only a problem if the BraceIndent error is excluded. If it is not excluded, BraceOnSameLine will not take into consideration the indentation, but BraceIndent will fix it. I suppose whether this is a bug depends on whether BraceOnSameLine is designed to rely on BraceIndent to correct the indentation, and if it is expected that the fixer of a particular error ignores the indentation, as demonstrated below.

Code sample

class MyClass {
    function foo() {
        return null;
    }
}

Custom ruleset

<?xml version="1.0"?>
<ruleset name="My Custom Standard">
    <rule ref="Generic.Functions.OpeningFunctionBraceBsdAllman">
        <exclude name="Generic.Functions.OpeningFunctionBraceBsdAllman.BraceIndent"/>
    </rule>
</ruleset>

To reproduce

Steps to reproduce the behavior:

  1. Create a file called test.php with the code sample above.
  2. Run phpcbf --standard=custom_standard.xml test.php

Expected behavior

I expect the fixed file to be:

class MyClass {
    function foo()
    {
        return null;
    }
}

But instead it is (note the indentation of the function opening brace):

class MyClass {
    function foo()
{
        return null;
    }
}

Versions (please complete the following information)

Operating System Ubuntu 24.04
PHP version 8.3
PHP_CodeSniffer version master
Standard Generic
Install type git clone

Please confirm

  • I have searched the issue list and am not opening a duplicate issue.
  • I have read the Contribution Guidelines and this is not a support question.
  • I confirm that this bug is a bug in PHP_CodeSniffer and not in one of the external standards.
  • I have verified the issue still exists in the master branch of PHP_CodeSniffer.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions