Browse Source

fix: Constant invocation detected in typed constants (#7892)

SharkyKZ 11 months ago
parent
commit
c825d7c600

+ 1 - 1
src/Tokenizer/TokensAnalyzer.php

@@ -383,7 +383,7 @@ final class TokensAnalyzer
             $prevIndex = $this->tokens->getPrevMeaningfulToken($prevIndex);
         }
 
-        if ($this->tokens[$prevIndex]->isGivenKind([CT::T_CONST_IMPORT, T_EXTENDS, CT::T_FUNCTION_IMPORT, T_IMPLEMENTS, T_INSTANCEOF, T_INSTEADOF, T_NAMESPACE, T_NEW, CT::T_NULLABLE_TYPE, CT::T_TYPE_COLON, T_USE, CT::T_USE_TRAIT, CT::T_TYPE_INTERSECTION])) {
+        if ($this->tokens[$prevIndex]->isGivenKind([CT::T_CONST_IMPORT, T_EXTENDS, CT::T_FUNCTION_IMPORT, T_IMPLEMENTS, T_INSTANCEOF, T_INSTEADOF, T_NAMESPACE, T_NEW, CT::T_NULLABLE_TYPE, CT::T_TYPE_COLON, T_USE, CT::T_USE_TRAIT, CT::T_TYPE_INTERSECTION, CT::T_TYPE_ALTERNATION, T_CONST, CT::T_DISJUNCTIVE_NORMAL_FORM_TYPE_PARENTHESIS_CLOSE])) {
             return false;
         }
 

+ 32 - 0
tests/Fixer/ConstantNotation/NativeConstantInvocationFixerTest.php

@@ -563,4 +563,36 @@ echo M_PI;
 
         yield ['<?php function foo ((\A&B)|(C&\D)|E\F|\G|(A&H\I)|(A&\J\K) $var) {}'];
     }
+
+    /**
+     * @dataProvider provideFixPhp83Cases
+     *
+     * @requires PHP 8.3
+     */
+    public function testFixPhp83(string $expected, string $input): void
+    {
+        $this->fixer->configure(['strict' => true]);
+        $this->doTest($expected, $input);
+    }
+
+    /**
+     * @return iterable<array{0: string, 1: string}>
+     */
+    public static function provideFixPhp83Cases(): iterable
+    {
+        yield [
+            '<?php class Foo {
+                public const string C1 = \PHP_EOL;
+                protected const string|int C2 = \PHP_EOL;
+                private const string|(A&B) C3 = BAR;
+                public const EnumA C4 = EnumA::FOO;
+            }',
+            '<?php class Foo {
+                public const string C1 = PHP_EOL;
+                protected const string|int C2 = \PHP_EOL;
+                private const string|(A&B) C3 = \BAR;
+                public const EnumA C4 = EnumA::FOO;
+            }',
+        ];
+    }
 }

+ 48 - 0
tests/Tokenizer/TokensAnalyzerTest.php

@@ -1509,6 +1509,54 @@ abstract class Baz
         ];
     }
 
+    /**
+     * @param array<int, bool> $expected
+     *
+     * @dataProvider provideIsConstantInvocationPhp83Cases
+     *
+     * @requires PHP 8.3
+     */
+    public function testIsConstantInvocationPhp83(array $expected, string $source): void
+    {
+        $this->doIsConstantInvocationTest($expected, $source);
+    }
+
+    /**
+     * @return iterable<array{array<int, bool>, string}>
+     */
+    public static function provideIsConstantInvocationPhp83Cases(): iterable
+    {
+        yield [
+            [3 => false, 11 => false, 13 => false, 17 => true],
+            '<?php class Foo { public const A FOO = BAR; }',
+        ];
+
+        yield [
+            [3 => false, 11 => false, 13 => false, 15 => false, 19 => true],
+            '<?php class Foo { public const A|B FOO = BAR; }',
+        ];
+
+        yield [
+            [3 => false, 11 => false, 13 => false, 15 => false, 19 => true],
+            '<?php class Foo { public const A&B FOO = BAR; }',
+        ];
+
+        yield [
+            [3 => false, 12 => false, 14 => false, 17 => false, 19 => false, 23 => true],
+            '<?php class Foo { public const (A&B)|C FOO = BAR; }',
+        ];
+
+        yield [
+            [3 => false, 12 => false, 14 => false, 18 => false, 20 => false, 23 => false, 27 => true],
+            '<?php class Foo { public const (A&B)|(C&D) FOO = BAR; }',
+        ];
+
+        yield [
+            [3 => false, 12 => false, 15 => false, 17 => false, 21 => false, 23 => false, 25 => false, 28 => false, 32 => true],
+            '<?php class Foo { public const (A&\B\C)|(D\E&F) FOO = BAR; }',
+        ];
+    }
+
     public function testIsConstantInvocationInvalid(): void
     {
         $this->expectException(\LogicException::class);