Browse Source

bug #5464 NativeFunctionInvocationFixer - PHP 8 attributes (HypeMC, keradus)

This PR was squashed before being merged into the 2.18 branch.

Discussion
----------

NativeFunctionInvocationFixer - PHP 8 attributes

The `NativeFunctionInvocationFixer` removes the leading `\` from attributes when strict is set to `true` which breaks the code.

Config:
```php
'native_function_invocation' => [
    'strict' => true,
],
```

Result:
```diff
-#[\Attribute(\Attribute::TARGET_CLASS)]
+#[Attribute(\Attribute::TARGET_CLASS)]
class Foo {}
```

This PR should fix the problem.

Commits
-------

54dbfc36e NativeFunctionInvocationFixer - PHP 8 attributes
Dariusz Ruminski 4 years ago
parent
commit
d3aaf70b1c

+ 8 - 1
src/Tokenizer/Analyzer/FunctionsAnalyzer.php

@@ -56,7 +56,14 @@ final class FunctionsAnalyzer
             $prevIndex = $tokens->getPrevMeaningfulToken($prevIndex);
         }
 
-        if ($tokens[$prevIndex]->isGivenKind([T_DOUBLE_COLON, T_FUNCTION, CT::T_NAMESPACE_OPERATOR, T_NEW, T_OBJECT_OPERATOR, CT::T_RETURN_REF, T_STRING])) {
+        $possibleKind = [T_DOUBLE_COLON, T_FUNCTION, CT::T_NAMESPACE_OPERATOR, T_NEW, T_OBJECT_OPERATOR, CT::T_RETURN_REF, T_STRING];
+
+        // @TODO: drop condition when PHP 8.0+ is required
+        if (\defined('T_ATTRIBUTE')) {
+            $possibleKind[] = T_ATTRIBUTE;
+        }
+
+        if ($tokens[$prevIndex]->isGivenKind($possibleKind)) {
             return false;
         }
 

+ 15 - 0
tests/Fixer/FunctionNotation/NativeFunctionInvocationFixerTest.php

@@ -645,4 +645,19 @@ echo strlen($a);
 '
         );
     }
+
+    /**
+     * @requires PHP 8.0
+     */
+    public function testFixWithAttributesAndStrict()
+    {
+        $this->testFixWithConfiguredInclude(
+            '<?php
+#[\Attribute(\Attribute::TARGET_CLASS)]
+class Foo {}
+',
+            null,
+            ['strict' => true]
+        );
+    }
 }

+ 17 - 7
tests/Tokenizer/Analyzer/FunctionsAnalyzerTest.php

@@ -348,32 +348,42 @@ A();
     }
 
     /**
-     * @param int[]  $globalFunctionIndexes
+     * @param bool   $isFunctionIndex
      * @param string $code
+     * @param int    $index
      *
      * @dataProvider provideIsGlobalFunctionCallPhp80Cases
      * @requires PHP 8.0
      */
-    public function testIsGlobalFunctionCallPhp80(array $globalFunctionIndexes, $code)
+    public function testIsGlobalFunctionCallPhp80($isFunctionIndex, $code, $index)
     {
         $tokens = Tokens::fromCode($code);
         $analyzer = new FunctionsAnalyzer();
 
-        foreach ($globalFunctionIndexes as $index) {
-            static::assertTrue($analyzer->isGlobalFunctionCall($tokens, $index));
-        }
+        static::assertSame($isFunctionIndex, $analyzer->isGlobalFunctionCall($tokens, $index));
     }
 
     public function provideIsGlobalFunctionCallPhp80Cases()
     {
         yield [
-            [8],
+            true,
             '<?php $a = new (foo());',
+            8,
         ];
 
         yield [
-            [10],
+            true,
             '<?php $b = $foo instanceof (foo());',
+            10,
+        ];
+
+        yield [
+            false,
+            '<?php
+#[\Attribute(\Attribute::TARGET_CLASS)]
+class Foo {}
+',
+            3,
         ];
     }