Browse Source

fix: CI for PHP 8.4 (#8114)

Kuba Werłos 7 months ago
parent
commit
4b6dfd5118

+ 6 - 2
src/Fixer/ArrayNotation/NormalizeIndexBraceFixer.php

@@ -15,9 +15,10 @@ declare(strict_types=1);
 namespace PhpCsFixer\Fixer\ArrayNotation;
 
 use PhpCsFixer\AbstractFixer;
-use PhpCsFixer\FixerDefinition\CodeSample;
 use PhpCsFixer\FixerDefinition\FixerDefinition;
 use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
+use PhpCsFixer\FixerDefinition\VersionSpecification;
+use PhpCsFixer\FixerDefinition\VersionSpecificCodeSample;
 use PhpCsFixer\Tokenizer\CT;
 use PhpCsFixer\Tokenizer\Token;
 use PhpCsFixer\Tokenizer\Tokens;
@@ -31,7 +32,10 @@ final class NormalizeIndexBraceFixer extends AbstractFixer
     {
         return new FixerDefinition(
             'Array index should always be written by using square braces.',
-            [new CodeSample("<?php\necho \$sample{\$index};\n")]
+            [new VersionSpecificCodeSample(
+                "<?php\necho \$sample{\$index};\n",
+                new VersionSpecification(null, 8_04_00 - 1)
+            )]
         );
     }
 

+ 23 - 2
tests/Fixer/Alias/ArrayPushFixerTest.php

@@ -176,8 +176,8 @@ final class ArrayPushFixerTest extends AbstractFixerTestCase
         ];
 
         yield [
-            '<?php $a->$c[1]->$d{$a--}->$a[7][] = $b;',
-            '<?php array_push($a->$c[1]->$d{$a--}->$a[7], $b);',
+            '<?php $a->$c[1]->$d[$a--]->$a[7][] = $b;',
+            '<?php array_push($a->$c[1]->$d[$a--]->$a[7], $b);',
         ];
 
         yield 'push multiple' => [
@@ -330,4 +330,25 @@ final class ArrayPushFixerTest extends AbstractFixerTestCase
             ',
         ];
     }
+
+    /**
+     * @dataProvider provideFixPre84Cases
+     *
+     * @requires PHP <8.4
+     */
+    public function testFixPre84(string $expected, string $input): void
+    {
+        $this->doTest($expected, $input);
+    }
+
+    /**
+     * @return iterable<array{string, string}>
+     */
+    public static function provideFixPre84Cases(): iterable
+    {
+        yield [
+            '<?php $a->$c[1]->$d{$a--}->$a[7][] = $b;',
+            '<?php array_push($a->$c[1]->$d{$a--}->$a[7], $b);',
+        ];
+    }
 }

+ 43 - 4
tests/Fixer/Basic/BracesFixerTest.php

@@ -212,8 +212,8 @@ final class BracesFixerTest extends AbstractFixerTestCase
         yield [
             '<?php
                     if (1) {
-                        echo $items{0}->foo;
-                        echo $collection->items{1}->property;
+                        echo $items[0]->foo;
+                        echo $collection->items[1]->property;
                     }
                 ',
         ];
@@ -471,8 +471,8 @@ final class BracesFixerTest extends AbstractFixerTestCase
         yield [
             '<?php
                     if (1) {
-                        echo $items{0}->foo;
-                        echo $collection->items{1}->property;
+                        echo $items[0]->foo;
+                        echo $collection->items[1]->property;
                     }
                 ',
             null,
@@ -6053,4 +6053,43 @@ break;
  case Bar = "bar";}',
         ];
     }
+
+    /**
+     * @param _AutogeneratedInputConfiguration $configuration
+     *
+     * @dataProvider provideFixPre84Cases
+     *
+     * @requires PHP <8.4
+     */
+    public function testFixPre84(string $expected, ?string $input = null, array $configuration = []): void
+    {
+        $this->fixer->configure($configuration);
+        $this->doTest($expected, $input);
+    }
+
+    /**
+     * @return iterable<array{0: string, 1?: ?string, 2?: _AutogeneratedInputConfiguration}>
+     */
+    public static function provideFixPre84Cases(): iterable
+    {
+        yield [
+            '<?php
+                    if (1) {
+                        echo $items{0}->foo;
+                        echo $collection->items{1}->property;
+                    }
+                ',
+        ];
+
+        yield [
+            '<?php
+                    if (1) {
+                        echo $items{0}->foo;
+                        echo $collection->items{1}->property;
+                    }
+                ',
+            null,
+            self::CONFIGURATION_OOP_POSITION_SAME_LINE,
+        ];
+    }
 }

+ 27 - 2
tests/Fixer/ControlStructure/NoUnneededControlParenthesesFixerTest.php

@@ -830,7 +830,7 @@ final class NoUnneededControlParenthesesFixerTest extends AbstractFixerTestCase
                 $a9 = $o->abc($a);
                 $a10 = $o->abc($a)[1];
                 $a11 = $o->{$bar};
-                $a12 = $o->{$c->d}($e)[1](2){$f}->$c[1]()?>
+                $a12 = $o->{$c->d}($e)[1](2)[$f]->$c[1]()?>
             ',
             '<?php
                 $ag = (($b)->A::$foo);
@@ -846,7 +846,7 @@ final class NoUnneededControlParenthesesFixerTest extends AbstractFixerTestCase
                 $a9 = (($o)->abc($a));
                 $a10 = (($o)->abc($a)[1]);
                 $a11 = (($o)->{$bar});
-                $a12 = (($o)->{$c->d}($e)[1](2){$f}->$c[1]())?>
+                $a12 = (($o)->{$c->d}($e)[1](2)[$f]->$c[1]())?>
             ',
         ];
 
@@ -1805,4 +1805,29 @@ enum Suit
 ',
         ];
     }
+
+    /**
+     * @param _AutogeneratedInputConfiguration $configuration
+     *
+     * @dataProvider provideFixPre84Cases
+     *
+     * @requires PHP <8.4
+     */
+    public function testFixPre84(string $expected, ?string $input = null, array $configuration = []): void
+    {
+        $this->fixer->configure($configuration);
+        $this->doTest($expected, $input);
+    }
+
+    /**
+     * @return iterable<array{string, string, _AutogeneratedInputConfiguration}>
+     */
+    public static function provideFixPre84Cases(): iterable
+    {
+        yield 'access' => [
+            '<?php $a = $o->{$c->d}($e)[1](2){$f}->$c[1]();',
+            '<?php $a = (($o)->{$c->d}($e)[1](2){$f}->$c[1]());',
+            ['statements' => ['others']],
+        ];
+    }
 }

+ 1 - 1
tests/Test/AbstractFixerTestCase.php

@@ -536,7 +536,7 @@ abstract class AbstractFixerTestCase extends TestCase
             YodaStyleFixerTest::class,
         ];
 
-        $names = ['Fix', 'Fix74Deprecated', 'FixPre80', 'Fix80', 'FixPre81', 'Fix81', 'Fix82', 'Fix83', 'Fix84', 'WithWhitespacesConfig', 'InvalidConfiguration'];
+        $names = ['Fix', 'Fix74Deprecated', 'FixPre80', 'Fix80', 'FixPre81', 'Fix81', 'Fix82', 'Fix83', 'FixPre84', 'Fix84', 'WithWhitespacesConfig', 'InvalidConfiguration'];
         $methodNames = ['testConfigure'];
         foreach ($names as $name) {
             $methodNames[] = 'test'.$name;

+ 18 - 2
tests/Tokenizer/Analyzer/ReferenceAnalyzerTest.php

@@ -123,8 +123,6 @@ class Foo {
 
         yield ['<?php foo($bar["mode"] & $baz);'];
 
-        yield ['<?php foo($bar{"mode"} & $baz);'];
-
         yield ['<?php foo(0b11111111 & $bar);'];
 
         yield ['<?php foo(127 & $bar);'];
@@ -148,6 +146,24 @@ class Foo {
         yield ['<?php function foo(?int $bar = BAZ & QUX) {};'];
     }
 
+    /**
+     * @dataProvider provideNonReferencePre84Cases
+     *
+     * @requires PHP <8.4
+     */
+    public function testNonReferencePre84(string $code): void
+    {
+        $this->doTestCode(false, $code);
+    }
+
+    /**
+     * @return iterable<array{string}>
+     */
+    public static function provideNonReferencePre84Cases(): iterable
+    {
+        yield ['<?php foo($bar{"mode"} & $baz);'];
+    }
+
     private function doTestCode(bool $expected, string $code): void
     {
         $analyzer = new ReferenceAnalyzer();

+ 41 - 5
tests/Tokenizer/TokensAnalyzerTest.php

@@ -1663,7 +1663,25 @@ abstract class Baz
             [5 => true],
             '<?php $a["foo"]++;',
         ];
+    }
+
+    /**
+     * @param array<int, bool> $expected
+     *
+     * @dataProvider provideIsUnarySuccessorOperatorPre84Cases
+     *
+     * @requires PHP <8.4
+     */
+    public function testIsUnarySuccessorOperatorPre84(array $expected, string $source): void
+    {
+        $this->testIsUnarySuccessorOperator($expected, $source);
+    }
 
+    /**
+     * @return iterable<array{array<int, bool>, string}>
+     */
+    public static function provideIsUnarySuccessorOperatorPre84Cases(): iterable
+    {
         yield 'array curly access' => [
             [5 => true],
             '<?php $a{"foo"}++;',
@@ -1834,11 +1852,6 @@ abstract class Baz
             '<?php echo $a[1] + 1;',
         ];
 
-        yield [
-            [8],
-            '<?php echo $a{1} + 1;',
-        ];
-
         yield [
             [3],
             '<?php $a .= $b; ?>',
@@ -2024,6 +2037,29 @@ $b;',
         ];
     }
 
+    /**
+     * @param list<int> $expected
+     *
+     * @dataProvider provideIsBinaryOperatorPre84Cases
+     *
+     * @requires PHP <8.4
+     */
+    public function testIsBinaryOperatorPre84(array $expected, string $source): void
+    {
+        $this->testIsBinaryOperator($expected, $source);
+    }
+
+    /**
+     * @return iterable<array{list<int>, string}>
+     */
+    public static function provideIsBinaryOperatorPre84Cases(): iterable
+    {
+        yield [
+            [8],
+            '<?php echo $a{1} + 1;',
+        ];
+    }
+
     /**
      * @dataProvider provideIsArrayCases
      */

+ 20 - 2
tests/Tokenizer/TokensTest.php

@@ -730,8 +730,6 @@ final class TokensTest extends TestCase
 
         yield [4, '<?php test(1);', Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, 2];
 
-        yield [4, '<?php $a{1};', Tokens::BLOCK_TYPE_ARRAY_INDEX_CURLY_BRACE, 2];
-
         yield [4, '<?php $a[1];', Tokens::BLOCK_TYPE_INDEX_SQUARE_BRACE, 2];
 
         yield [6, '<?php [1, "foo"];', Tokens::BLOCK_TYPE_ARRAY_SQUARE_BRACE, 1];
@@ -848,6 +846,26 @@ final class TokensTest extends TestCase
         }
     }
 
+    /**
+     * @param Tokens::BLOCK_TYPE_* $type
+     *
+     * @dataProvider provideFindBlockEndPre84Cases
+     *
+     * @requires PHP <8.4
+     */
+    public function testFindBlockEndPre84(int $expectedIndex, string $source, int $type, int $searchIndex): void
+    {
+        self::assertFindBlockEnd($expectedIndex, $source, $type, $searchIndex);
+    }
+
+    /**
+     * @return iterable<array{int, string, int, int}>
+     */
+    public static function provideFindBlockEndPre84Cases(): iterable
+    {
+        yield [4, '<?php $a{1};', Tokens::BLOCK_TYPE_ARRAY_INDEX_CURLY_BRACE, 2];
+    }
+
     public function testFindBlockEndInvalidType(): void
     {
         Tokens::clearCache();

+ 42 - 1
tests/Tokenizer/Transformer/BraceClassInstantiationTransformerTest.php

@@ -106,7 +106,7 @@ final class BraceClassInstantiationTransformerTest extends AbstractTransformerTe
         ];
 
         yield [
-            '<?php $foo{0}(new Foo())->bar();',
+            '<?php $foo[0](new Foo())->bar();',
             [
                 5 => '(',
                 9 => '(',
@@ -504,4 +504,45 @@ function test2($param = (new Foo)) {}
 ',
         ];
     }
+
+    /**
+     * @param array<int, int|string> $expectedTokens
+     * @param list<int>              $observedKinds
+     *
+     * @dataProvider provideProcessPrePhp84Cases
+     *
+     * @requires PHP <8.4
+     */
+    public function testProcessPrePhp84(string $source, array $expectedTokens, array $observedKinds = []): void
+    {
+        $this->doTest(
+            $source,
+            $expectedTokens,
+            $observedKinds
+        );
+    }
+
+    /**
+     * @return iterable<array{string, array<int, string>, list<int|string>}>
+     */
+    public static function provideProcessPrePhp84Cases(): iterable
+    {
+        yield [
+            '<?php $foo{0}(new Foo())->bar();',
+            [
+                5 => '(',
+                9 => '(',
+                10 => ')',
+                11 => ')',
+                14 => '(',
+                15 => ')',
+            ],
+            [
+                '(',
+                ')',
+                CT::T_BRACE_CLASS_INSTANTIATION_OPEN,
+                CT::T_BRACE_CLASS_INSTANTIATION_CLOSE,
+            ],
+        ];
+    }
 }

+ 139 - 69
tests/Tokenizer/Transformer/BraceTransformerTest.php

@@ -106,67 +106,6 @@ final class BraceTransformerTest extends AbstractTransformerTestCase
             ],
         ];
 
-        yield 'array index curly brace open/close' => [
-            '<?php
-                    echo $arr{$index};
-                    echo $arr[$index];
-                    if (1) {}
-                ',
-            [
-                5 => CT::T_ARRAY_INDEX_CURLY_BRACE_OPEN,
-                7 => CT::T_ARRAY_INDEX_CURLY_BRACE_CLOSE,
-            ],
-        ];
-
-        yield 'array index curly brace open/close, after square index' => [
-            '<?php $b = [1]{0};
-                ',
-            [
-                8 => CT::T_ARRAY_INDEX_CURLY_BRACE_OPEN,
-                10 => CT::T_ARRAY_INDEX_CURLY_BRACE_CLOSE,
-            ],
-        ];
-
-        yield 'array index curly brace open/close, nested' => [
-            '<?php
-                    echo $nestedArray{$index}{$index2}[$index3]{$index4};
-                ',
-            [
-                5 => CT::T_ARRAY_INDEX_CURLY_BRACE_OPEN,
-                7 => CT::T_ARRAY_INDEX_CURLY_BRACE_CLOSE,
-                8 => CT::T_ARRAY_INDEX_CURLY_BRACE_OPEN,
-                10 => CT::T_ARRAY_INDEX_CURLY_BRACE_CLOSE,
-                14 => CT::T_ARRAY_INDEX_CURLY_BRACE_OPEN,
-                16 => CT::T_ARRAY_INDEX_CURLY_BRACE_CLOSE,
-            ],
-        ];
-
-        yield 'array index curly brace open/close, repeated' => [
-            '<?php
-                    echo $array{0}->foo;
-                    echo $collection->items{1}->property;
-                ',
-            [
-                5 => CT::T_ARRAY_INDEX_CURLY_BRACE_OPEN,
-                7 => CT::T_ARRAY_INDEX_CURLY_BRACE_CLOSE,
-                17 => CT::T_ARRAY_INDEX_CURLY_BRACE_OPEN,
-                19 => CT::T_ARRAY_INDEX_CURLY_BRACE_CLOSE,
-            ],
-        ];
-
-        yield 'array index curly brace open/close, minimal' => [
-            '<?php
-                    echo [1]{0};
-                    echo array(1){0};
-                ',
-            [
-                7 => CT::T_ARRAY_INDEX_CURLY_BRACE_OPEN,
-                9 => CT::T_ARRAY_INDEX_CURLY_BRACE_CLOSE,
-                18 => CT::T_ARRAY_INDEX_CURLY_BRACE_OPEN,
-                20 => CT::T_ARRAY_INDEX_CURLY_BRACE_CLOSE,
-            ],
-        ];
-
         yield 'mixed' => [
             '<?php echo "This is {$great}";
                     $a = "a{$b->c()}d";
@@ -259,6 +198,102 @@ final class BraceTransformerTest extends AbstractTransformerTestCase
         ];
     }
 
+    /**
+     * @param array<int, int> $expectedTokens
+     *
+     * @dataProvider providePre84ProcessCases
+     *
+     * @requires PHP <8.4
+     */
+    public function testPre84Process(string $source, array $expectedTokens = []): void
+    {
+        $this->doTest(
+            $source,
+            $expectedTokens,
+            [
+                T_CURLY_OPEN,
+                CT::T_CURLY_CLOSE,
+                T_DOLLAR_OPEN_CURLY_BRACES,
+                CT::T_DOLLAR_CLOSE_CURLY_BRACES,
+                CT::T_DYNAMIC_PROP_BRACE_OPEN,
+                CT::T_DYNAMIC_PROP_BRACE_CLOSE,
+                CT::T_DYNAMIC_VAR_BRACE_OPEN,
+                CT::T_DYNAMIC_VAR_BRACE_CLOSE,
+                CT::T_ARRAY_INDEX_CURLY_BRACE_OPEN,
+                CT::T_ARRAY_INDEX_CURLY_BRACE_CLOSE,
+                CT::T_GROUP_IMPORT_BRACE_OPEN,
+                CT::T_GROUP_IMPORT_BRACE_CLOSE,
+            ]
+        );
+    }
+
+    /**
+     * @return iterable<array{string, array<int, int>}>
+     */
+    public static function providePre84ProcessCases(): iterable
+    {
+        yield 'array index curly brace open/close' => [
+            '<?php
+                    echo $arr{$index};
+                    echo $arr[$index];
+                    if (1) {}
+                ',
+            [
+                5 => CT::T_ARRAY_INDEX_CURLY_BRACE_OPEN,
+                7 => CT::T_ARRAY_INDEX_CURLY_BRACE_CLOSE,
+            ],
+        ];
+
+        yield 'array index curly brace open/close, after square index' => [
+            '<?php $b = [1]{0};
+                ',
+            [
+                8 => CT::T_ARRAY_INDEX_CURLY_BRACE_OPEN,
+                10 => CT::T_ARRAY_INDEX_CURLY_BRACE_CLOSE,
+            ],
+        ];
+
+        yield 'array index curly brace open/close, nested' => [
+            '<?php
+                    echo $nestedArray{$index}{$index2}[$index3]{$index4};
+                ',
+            [
+                5 => CT::T_ARRAY_INDEX_CURLY_BRACE_OPEN,
+                7 => CT::T_ARRAY_INDEX_CURLY_BRACE_CLOSE,
+                8 => CT::T_ARRAY_INDEX_CURLY_BRACE_OPEN,
+                10 => CT::T_ARRAY_INDEX_CURLY_BRACE_CLOSE,
+                14 => CT::T_ARRAY_INDEX_CURLY_BRACE_OPEN,
+                16 => CT::T_ARRAY_INDEX_CURLY_BRACE_CLOSE,
+            ],
+        ];
+
+        yield 'array index curly brace open/close, repeated' => [
+            '<?php
+                    echo $array{0}->foo;
+                    echo $collection->items{1}->property;
+                ',
+            [
+                5 => CT::T_ARRAY_INDEX_CURLY_BRACE_OPEN,
+                7 => CT::T_ARRAY_INDEX_CURLY_BRACE_CLOSE,
+                17 => CT::T_ARRAY_INDEX_CURLY_BRACE_OPEN,
+                19 => CT::T_ARRAY_INDEX_CURLY_BRACE_CLOSE,
+            ],
+        ];
+
+        yield 'array index curly brace open/close, minimal' => [
+            '<?php
+                    echo [1]{0};
+                    echo array(1){0};
+                ',
+            [
+                7 => CT::T_ARRAY_INDEX_CURLY_BRACE_OPEN,
+                9 => CT::T_ARRAY_INDEX_CURLY_BRACE_CLOSE,
+                18 => CT::T_ARRAY_INDEX_CURLY_BRACE_OPEN,
+                20 => CT::T_ARRAY_INDEX_CURLY_BRACE_CLOSE,
+            ],
+        ];
+    }
+
     /**
      * @dataProvider provideNotDynamicClassConstantFetchCases
      */
@@ -329,14 +364,6 @@ final class BraceTransformerTest extends AbstractTransformerTestCase
             '<?php echo Foo::{$bar};',
         ];
 
-        yield 'static method var, string' => [
-            [
-                10 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_OPEN,
-                12 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_CLOSE,
-            ],
-            "<?php echo Foo::{\$static_method}(){'XYZ'};",
-        ];
-
         yield 'long way of writing `Bar::class`' => [
             [
                 5 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_OPEN,
@@ -395,6 +422,49 @@ final class BraceTransformerTest extends AbstractTransformerTestCase
             "<?php echo Foo::{'BAR'}::{'BLA'}::{static_method}(1,2) ?>",
         ];
 
+        yield 'mixed chain' => [
+            [
+                21 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_OPEN,
+                23 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_CLOSE,
+                25 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_OPEN,
+                27 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_CLOSE,
+            ],
+            '<?php echo Foo::{\'static_method\'}()::{$$a}()["const"]::{some_const}::{$other_const}::{$last_static_method}();',
+        ];
+    }
+
+    /**
+     * @param array<int, int> $expectedTokens
+     *
+     * @dataProvider provideDynamicClassConstantFetchPhp83Cases
+     *
+     * @requires PHP ~8.3.0
+     */
+    public function testDynamicClassConstantFetchPhp83(array $expectedTokens, string $source): void
+    {
+        $this->doTest(
+            $source,
+            $expectedTokens,
+            [
+                CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_OPEN,
+                CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_CLOSE,
+            ],
+        );
+    }
+
+    /**
+     * @return iterable<array{array<int, int>, string}>
+     */
+    public static function provideDynamicClassConstantFetchPhp83Cases(): iterable
+    {
+        yield 'static method var, string' => [
+            [
+                10 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_OPEN,
+                12 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_CLOSE,
+            ],
+            "<?php echo Foo::{\$static_method}(){'XYZ'};",
+        ];
+
         yield 'mixed chain' => [
             [
                 17 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_OPEN,