From 217082381520c46fcfb4c47c15d32e0f55e862c9 Mon Sep 17 00:00:00 2001 From: Payton Swick Date: Sun, 17 Nov 2024 18:38:25 -0500 Subject: [PATCH 1/2] Add test for nested arrow functions --- .../fixtures/ArrowFunctionFixture.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Tests/VariableAnalysisSniff/fixtures/ArrowFunctionFixture.php b/Tests/VariableAnalysisSniff/fixtures/ArrowFunctionFixture.php index 9a16dc4..f3f48e8 100644 --- a/Tests/VariableAnalysisSniff/fixtures/ArrowFunctionFixture.php +++ b/Tests/VariableAnalysisSniff/fixtures/ArrowFunctionFixture.php @@ -166,3 +166,12 @@ function arrowFunctionWithQuotes($allowedReferrers) { && $permissionName !== CustomPermission::ALL_CONFIG ); } + +function arrowFunctionWithNestedArrowFunction() { + $fn = fn($outerArrowArg) => [ + $outerArrowArg, + fn($insideArg) => $insideArg, + $outerArrowArg, + ]; + $fn(); +} From 8d6ab7cc9195b919b7609e170a6cb867abd2b1fe Mon Sep 17 00:00:00 2001 From: Payton Swick Date: Sun, 17 Nov 2024 20:12:21 -0500 Subject: [PATCH 2/2] Prevent finding a nested arrow function when searching for the start --- VariableAnalysis/Lib/Helpers.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/VariableAnalysis/Lib/Helpers.php b/VariableAnalysis/Lib/Helpers.php index dfcdc38..6af1b22 100644 --- a/VariableAnalysis/Lib/Helpers.php +++ b/VariableAnalysis/Lib/Helpers.php @@ -608,6 +608,17 @@ private static function getPreviousArrowFunctionIndex(File $phpcsFile, $stackPtr if ($token['content'] === 'fn' && self::isArrowFunction($phpcsFile, $index)) { return $index; } + // If we find a token that would close an arrow function scope before we + // find a token that would open an arrow function scope, then we've found + // a nested arrow function and we should ignore it, move back before THAT + // arrow function's scope, and continue to search. + $arrowFunctionStartIndex = $phpcsFile->findPrevious([T_FN], $index, $enclosingScopeIndex); + if (is_int($arrowFunctionStartIndex)) { + $openClose = self::getArrowFunctionOpenClose($phpcsFile, $arrowFunctionStartIndex); + if ($openClose && $openClose['scope_closer'] === $index) { + $index = $openClose['scope_opener']; + } + } } return null; } @@ -646,6 +657,15 @@ public static function isArrowFunction(File $phpcsFile, $stackPtr) } /** + * Find the opening and closing scope positions for an arrow function if the + * given position is the start of the arrow function (the `fn` keyword + * token). + * + * Returns null if the passed token is not an arrow function keyword. + * + * If the token is an arrow function keyword, the scope opener is returned as + * the provided position. + * * @param File $phpcsFile * @param int $stackPtr *