|
@@ -16,6 +16,7 @@ namespace PhpCsFixer\Tests\Tokenizer\Transformer;
|
|
|
|
|
|
use PhpCsFixer\Tests\Test\AbstractTransformerTestCase;
|
|
|
use PhpCsFixer\Tokenizer\CT;
|
|
|
+use PhpCsFixer\Tokenizer\Tokens;
|
|
|
|
|
|
/**
|
|
|
* @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
|
|
@@ -237,7 +238,7 @@ final class CurlyBraceTransformerTest extends AbstractTransformerTestCase
|
|
|
public static function provideProcess80Cases(): array
|
|
|
{
|
|
|
return [
|
|
|
- 'dynamic property brace open/close' => [
|
|
|
+ 'dynamic nullable property brace open/close' => [
|
|
|
'<?php $foo?->{$bar};',
|
|
|
[
|
|
|
3 => CT::T_DYNAMIC_PROP_BRACE_OPEN,
|
|
@@ -246,4 +247,153 @@ final class CurlyBraceTransformerTest extends AbstractTransformerTestCase
|
|
|
],
|
|
|
];
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @dataProvider provideNotDynamicClassConstantFetchCases
|
|
|
+ */
|
|
|
+ public function testNotDynamicClassConstantFetch(string $source): void
|
|
|
+ {
|
|
|
+ Tokens::clearCache();
|
|
|
+ $tokens = Tokens::fromCode($source);
|
|
|
+
|
|
|
+ self::assertFalse(
|
|
|
+ $tokens->isAnyTokenKindsFound(
|
|
|
+ [
|
|
|
+ CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_OPEN,
|
|
|
+ CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_CLOSE,
|
|
|
+ ]
|
|
|
+ )
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ public static function provideNotDynamicClassConstantFetchCases(): iterable
|
|
|
+ {
|
|
|
+ yield 'negatives' => [
|
|
|
+ '<?php
|
|
|
+ namespace B {$b = Z::B;};
|
|
|
+
|
|
|
+ echo $c::{$static_method}();
|
|
|
+ echo Foo::{$static_method}();
|
|
|
+
|
|
|
+ echo Foo::${static_property};
|
|
|
+ echo Foo::${$static_property};
|
|
|
+
|
|
|
+ echo Foo::class;
|
|
|
+
|
|
|
+ echo $foo::$bar;
|
|
|
+ echo $foo::bar();
|
|
|
+ echo foo()::A();
|
|
|
+
|
|
|
+ {$z = A::C;}
|
|
|
+ ',
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param array<int, int> $expectedTokens
|
|
|
+ *
|
|
|
+ * @dataProvider provideDynamicClassConstantFetchCases
|
|
|
+ *
|
|
|
+ * @requires PHP 8.3
|
|
|
+ */
|
|
|
+ public function testDynamicClassConstantFetch(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,
|
|
|
+ ],
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ public static function provideDynamicClassConstantFetchCases(): iterable
|
|
|
+ {
|
|
|
+ yield 'simple' => [
|
|
|
+ [
|
|
|
+ 5 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_OPEN,
|
|
|
+ 7 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_CLOSE,
|
|
|
+ ],
|
|
|
+ '<?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,
|
|
|
+ 7 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_CLOSE,
|
|
|
+ ],
|
|
|
+ "<?php echo Bar::{'class'};",
|
|
|
+ ];
|
|
|
+
|
|
|
+ yield 'variable variable wrapped, close tag' => [
|
|
|
+ [
|
|
|
+ 5 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_OPEN,
|
|
|
+ 10 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_CLOSE,
|
|
|
+ ],
|
|
|
+ '<?php echo Foo::{${$var}}?>',
|
|
|
+ ];
|
|
|
+
|
|
|
+ yield 'variable variable, comment' => [
|
|
|
+ [
|
|
|
+ 5 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_OPEN,
|
|
|
+ 8 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_CLOSE,
|
|
|
+ ],
|
|
|
+ '<?php echo Foo::{$$var}/* */;?>',
|
|
|
+ ];
|
|
|
+
|
|
|
+ yield 'static, self' => [
|
|
|
+ [
|
|
|
+ 37 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_OPEN,
|
|
|
+ 39 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_CLOSE,
|
|
|
+ 46 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_OPEN,
|
|
|
+ 48 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_CLOSE,
|
|
|
+ 55 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_OPEN,
|
|
|
+ 57 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_CLOSE,
|
|
|
+ ],
|
|
|
+ '<?php
|
|
|
+ class Foo
|
|
|
+ {
|
|
|
+ private const X = 1;
|
|
|
+
|
|
|
+ public function Bar($var): void
|
|
|
+ {
|
|
|
+ echo self::{$var};
|
|
|
+ echo static::{$var};
|
|
|
+ echo static::{"X"};
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ',
|
|
|
+ ];
|
|
|
+
|
|
|
+ yield 'chained' => [
|
|
|
+ [
|
|
|
+ 5 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_OPEN,
|
|
|
+ 7 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_CLOSE,
|
|
|
+ 9 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_OPEN,
|
|
|
+ 11 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_CLOSE,
|
|
|
+ ],
|
|
|
+ "<?php echo Foo::{'BAR'}::{'BLA'}::{static_method}(1,2) ?>",
|
|
|
+ ];
|
|
|
+
|
|
|
+ yield 'mixed chain' => [
|
|
|
+ [
|
|
|
+ 17 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_OPEN,
|
|
|
+ 19 => CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_CLOSE,
|
|
|
+ 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}();',
|
|
|
+ ];
|
|
|
+ }
|
|
|
}
|