You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
PEAR.WhiteSpace.ObjectOperatorIndent expects wrong indentation when there are multiple chained calls in the same statement #1154
If you have multiple chained calls within the same statement (for example, an array where multiple elements consist of chained method calls), but using different indentation, then the PEAR.WhiteSpace.ObjectOperatorIndent sniff will expect an incorrect amount of indentation.
But the whole array literal in the above example is just one statement. So, when analyzing the chained calls at line 8, $next will find the chained calls at line 10-11 and expect them to be indented like the ones at line 8.
Please confirm
I have searched the issue list and am not opening a duplicate issue.
But the whole array literal in the above example is just one statement. So, when analyzing the chained calls at line 8, $next will find the chained calls at line 10-11 and expect them to be indented like the ones at line 8.
I believe the problem is actually in another part of the code. The call to File::findEndOfStatement() correctly identifies the comma as the end of the statement and assigns its position to $end. $end is used to limit the scope of the search performed by File::fileNext(), and thus it does not include the chained calls on lines 10-11.
Below, the sniff loops over all the object operators in a given chained call using a while loop:
I believe the problem is that the sniff is relying on the $local parameter of findNext() to limit the scope of the search, and $local only considers a semicolon as the end of a statement:
if ($local === true && $this->tokens[$i]['code'] === T_SEMICOLON) {
break;
}
Different chained calls are not necessarily separated by a semicolon (as in the example that was provided). This means that the sniff currently considers the object operators on the second chained method call as part of the first chained method call and checks their indentation using the indentation of the first element on the first chained call as its base.
Unless I'm missing something, this is a relatively easy fix to make, and I will prepare a PR for it.
Activity
rodrigoprimo commentedon Jul 1, 2025
Thanks for copying this issue from the old repository, @Daimona. Also, thanks to @lucassabreu for the original report.
I was able to reproduce it. Here is a simplified code snippet that produces the same bug:
I believe the problem is actually in another part of the code. The call to
File::findEndOfStatement()correctly identifies the comma as the end of the statement and assigns its position to$end.$endis used to limit the scope of the search performed byFile::fileNext(), and thus it does not include the chained calls on lines 10-11.Below, the sniff loops over all the object operators in a given chained call using a
whileloop:PHP_CodeSniffer/src/Standards/PEAR/Sniffs/WhiteSpace/ObjectOperatorIndentSniff.php
Line 118 in 368817d
Here is the code where
$nextis reassigned to the next object operator:PHP_CodeSniffer/src/Standards/PEAR/Sniffs/WhiteSpace/ObjectOperatorIndentSniff.php
Lines 191 to 198 in 368817d
I believe the problem is that the sniff is relying on the
$localparameter offindNext()to limit the scope of the search, and$localonly considers a semicolon as the end of a statement:PHP_CodeSniffer/src/Files/File.php
Lines 2422 to 2424 in 2e9da03
Different chained calls are not necessarily separated by a semicolon (as in the example that was provided). This means that the sniff currently considers the object operators on the second chained method call as part of the first chained method call and checks their indentation using the indentation of the first element on the first chained call as its base.
Unless I'm missing something, this is a relatively easy fix to make, and I will prepare a PR for it.