Browse Source

feat: `UseArrowFunctionsFixer` - support multiline statements (#8311)

Kuba Werłos 3 months ago
parent
commit
23534bff9e

+ 1 - 1
doc/rules/function_notation/use_arrow_functions.rst

@@ -2,7 +2,7 @@
 Rule ``use_arrow_functions``
 ============================
 
-Anonymous functions with one-liner return statement must use arrow functions.
+Anonymous functions with return as the only statement must use arrow functions.
 
 Warning
 -------

+ 1 - 1
doc/rules/index.rst

@@ -427,7 +427,7 @@ Function Notation
   Lambdas not (indirectly) referencing ``$this`` must be declared ``static``.
 - `use_arrow_functions <./function_notation/use_arrow_functions.rst>`_ *(risky)*
 
-  Anonymous functions with one-liner return statement must use arrow functions.
+  Anonymous functions with return as the only statement must use arrow functions.
 - `void_return <./function_notation/void_return.rst>`_ *(risky)*
 
   Add ``void`` return type to functions with missing or empty return statements, but priority is given to ``@return`` annotations.

+ 2 - 24
src/Fixer/FunctionNotation/UseArrowFunctionsFixer.php

@@ -31,7 +31,7 @@ final class UseArrowFunctionsFixer extends AbstractFixer
     public function getDefinition(): FixerDefinitionInterface
     {
         return new FixerDefinition(
-            'Anonymous functions with one-liner return statement must use arrow functions.',
+            'Anonymous functions with return as the only statement must use arrow functions.',
             [
                 new CodeSample(
                     <<<'SAMPLE'
@@ -78,8 +78,7 @@ final class UseArrowFunctionsFixer extends AbstractFixer
                 continue;
             }
 
-            // Find parameters end
-            // Abort if they are multilined
+            // Find parameters
 
             $parametersStart = $tokens->getNextMeaningfulToken($index);
 
@@ -89,10 +88,6 @@ final class UseArrowFunctionsFixer extends AbstractFixer
 
             $parametersEnd = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $parametersStart);
 
-            if ($this->isMultilined($tokens, $parametersStart, $parametersEnd)) {
-                continue;
-            }
-
             // Find `use ()` start and end
             // Abort if it contains reference variables
 
@@ -158,29 +153,12 @@ final class UseArrowFunctionsFixer extends AbstractFixer
                 continue;
             }
 
-            // Abort if the `return` statement is multilined
-
-            if ($this->isMultilined($tokens, $return, $semicolon)) {
-                continue;
-            }
-
             // Transform the function to an arrow function
 
             $this->transform($tokens, $index, $useStart, $useEnd, $braceOpen, $return, $semicolon, $braceClose);
         }
     }
 
-    private function isMultilined(Tokens $tokens, int $start, int $end): bool
-    {
-        for ($i = $start; $i < $end; ++$i) {
-            if (str_contains($tokens[$i]->getContent(), "\n")) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
     private function transform(Tokens $tokens, int $index, ?int $useStart, ?int $useEnd, int $braceOpen, int $return, int $semicolon, int $braceClose): void
     {
         $tokensToInsert = [new Token([T_DOUBLE_ARROW, '=>'])];

+ 33 - 4
tests/Fixer/FunctionNotation/UseArrowFunctionsFixerTest.php

@@ -152,17 +152,29 @@ final class UseArrowFunctionsFixerTest extends AbstractFixerTestCase
         ];
 
         yield [
-            <<<'EXPECTED'
+            <<<'PHP'
+                <?php
+                    foo(fn () =>
+                            1);
+                PHP,
+            <<<'PHP'
                 <?php
                     foo(function () {
                         return
                             1;
                     });
-                EXPECTED,
+                PHP,
         ];
 
         yield [
-            <<<'EXPECTED'
+            <<<'PHP'
+                <?php
+                    $func = fn (
+                        $a,
+                        $b
+                    ) => 1;
+                PHP,
+            <<<'PHP'
                 <?php
                     $func = function (
                         $a,
@@ -170,7 +182,7 @@ final class UseArrowFunctionsFixerTest extends AbstractFixerTestCase
                     ) {
                         return 1;
                     };
-                EXPECTED,
+                PHP,
         ];
 
         yield [
@@ -198,5 +210,22 @@ final class UseArrowFunctionsFixerTest extends AbstractFixerTestCase
             '<?php $testDummy = fn () => null/* foo */;',
             '<?php $testDummy = function () { return/* foo */; };',
         ];
+
+        yield [
+            <<<'PHP'
+                <?php return fn () => [
+                        CONST_A,
+                        CONST_B,
+                    ];
+                PHP,
+            <<<'PHP'
+                <?php return function () {
+                    return [
+                        CONST_A,
+                        CONST_B,
+                    ];
+                };
+                PHP,
+        ];
     }
 }