Skip to content

Commit 2914011

Browse files
committed
Fixed bug #2895 : PSR2.Methods.FunctionCallSignature.MultipleArguments false positive with arrow function argument
1 parent 1dbc333 commit 2914011

File tree

5 files changed

+62
-5
lines changed

5 files changed

+62
-5
lines changed

package.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
4141
- Fixed bug #2865 : Double arrow tokenized as T_STRING when placed after function named "fn"
4242
- Fixed bug #2868 : phpcs:ignore annotation doesnt work inside a docblock
4343
- Fixed bug #2878 : PSR12.Files.FileHeader conflicts with Generic.Files.LineEndings
44+
- Fixed bug #2895 : PSR2.Methods.FunctionCallSignature.MultipleArguments false positive with arrow function argument
4445
</notes>
4546
<contents>
4647
<dir name="/">

src/Files/File.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2333,7 +2333,6 @@ public function findEndOfStatement($start, $ignore=null)
23332333
}
23342334

23352335
$lastNotEmpty = $start;
2336-
23372336
for ($i = $start; $i < $this->numTokens; $i++) {
23382337
if ($i !== $start && isset($endTokens[$this->tokens[$i]['code']]) === true) {
23392338
// Found the end of the statement.
@@ -2356,7 +2355,8 @@ public function findEndOfStatement($start, $ignore=null)
23562355
|| $i === $this->tokens[$i]['scope_condition'])
23572356
) {
23582357
if ($this->tokens[$i]['code'] === T_FN) {
2359-
$i = ($this->tokens[$i]['scope_closer'] - 1);
2358+
$lastNotEmpty = $this->tokens[$i]['scope_closer'];
2359+
$i = ($this->tokens[$i]['scope_closer'] - 1);
23602360
continue;
23612361
}
23622362

src/Tokenizers/PHP.php

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1851,10 +1851,18 @@ protected function processAdditional()
18511851
T_CLOSE_TAG => true,
18521852
];
18531853

1854-
$inTernary = false;
1854+
$inTernary = false;
1855+
$lastEndToken = null;
18551856

18561857
for ($scopeCloser = ($arrow + 1); $scopeCloser < $numTokens; $scopeCloser++) {
18571858
if (isset($endTokens[$this->tokens[$scopeCloser]['code']]) === true) {
1859+
if ($lastEndToken !== null
1860+
&& $this->tokens[$scopeCloser]['code'] === T_CLOSE_PARENTHESIS
1861+
&& $this->tokens[$scopeCloser]['parenthesis_opener'] < $arrow
1862+
) {
1863+
$scopeCloser = $lastEndToken;
1864+
}
1865+
18581866
break;
18591867
}
18601868

@@ -1867,12 +1875,14 @@ protected function processAdditional()
18671875
}
18681876

18691877
if (isset($this->tokens[$scopeCloser]['parenthesis_closer']) === true) {
1870-
$scopeCloser = $this->tokens[$scopeCloser]['parenthesis_closer'];
1878+
$scopeCloser = $this->tokens[$scopeCloser]['parenthesis_closer'];
1879+
$lastEndToken = $scopeCloser;
18711880
continue;
18721881
}
18731882

18741883
if (isset($this->tokens[$scopeCloser]['bracket_closer']) === true) {
1875-
$scopeCloser = $this->tokens[$scopeCloser]['bracket_closer'];
1884+
$scopeCloser = $this->tokens[$scopeCloser]['bracket_closer'];
1885+
$lastEndToken = $scopeCloser;
18761886
continue;
18771887
}
18781888

@@ -1895,6 +1905,10 @@ protected function processAdditional()
18951905
if (PHP_CODESNIFFER_VERBOSITY > 1) {
18961906
$line = $this->tokens[$i]['line'];
18971907
echo "\t=> token $i on line $line processed as arrow function".PHP_EOL;
1908+
echo "\t\t* scope opener set to $arrow *".PHP_EOL;
1909+
echo "\t\t* scope closer set to $scopeCloser *".PHP_EOL;
1910+
echo "\t\t* parenthesis opener set to $x *".PHP_EOL;
1911+
echo "\t\t* parenthesis closer set to $closer *".PHP_EOL;
18981912
}
18991913

19001914
$this->tokens[$i]['code'] = T_FN;

tests/Core/File/FindEndOfStatementTest.inc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,14 @@ static fn ($a) => $a;
4242
/* testArrowFunctionReturnValue */
4343
fn(): array => [a($a, $b)];
4444

45+
/* testArrowFunctionAsArgument */
46+
$foo = foo(
47+
fn() => bar()
48+
);
49+
50+
/* testArrowFunctionWithArrayAsArgument */
51+
$foo = foo(
52+
fn() => [$row[0], $row[3]]
53+
);
54+
4555
return 0;

tests/Core/File/FindEndOfStatementTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,4 +222,36 @@ public function testArrowFunctionReturnValue()
222222
}//end testArrowFunctionReturnValue()
223223

224224

225+
/**
226+
* Test arrow function used as a function argument.
227+
*
228+
* @return void
229+
*/
230+
public function testArrowFunctionAsArgument()
231+
{
232+
$start = (self::$phpcsFile->findNext(T_COMMENT, 0, null, false, '/* testArrowFunctionAsArgument */') + 10);
233+
$found = self::$phpcsFile->findEndOfStatement($start);
234+
235+
$tokens = self::$phpcsFile->getTokens();
236+
$this->assertSame($tokens[($start + 8)], $tokens[$found]);
237+
238+
}//end testArrowFunctionAsArgument()
239+
240+
241+
/**
242+
* Test arrow function with arrays used as a function argument.
243+
*
244+
* @return void
245+
*/
246+
public function testArrowFunctionWithArrayAsArgument()
247+
{
248+
$start = (self::$phpcsFile->findNext(T_COMMENT, 0, null, false, '/* testArrowFunctionWithArrayAsArgument */') + 10);
249+
$found = self::$phpcsFile->findEndOfStatement($start);
250+
251+
$tokens = self::$phpcsFile->getTokens();
252+
$this->assertSame($tokens[($start + 17)], $tokens[$found]);
253+
254+
}//end testArrowFunctionWithArrayAsArgument()
255+
256+
225257
}//end class

0 commit comments

Comments
 (0)