Skip to content

Commit 2a0925d

Browse files
author
Matt Turland
committed
PHP 8.0: NewNestedStaticAccess: add support for class constant dereferencing
> ... class constant accesses are only array and object dereferencable. This > means that while `Foo::$bar::$baz` is legal, `Foo::BAR::$baz` is not. > > This RFC proposes to make class constant accesses static derefencable as > well, so that `Foo::BAR::$baz` and `Foo::BAR::BAZ` become legal. Ref: * https://wiki.php.net/rfc/variable_syntax_tweaks#class_constant_dereferencability * php/php-src#5061 * php/php-src@ab154b7 Includes unit tests. Relates to PHPCompatibility#809.
1 parent 0da6d71 commit 2a0925d

File tree

3 files changed

+53
-11
lines changed

3 files changed

+53
-11
lines changed

PHPCompatibility/Sniffs/Syntax/NewNestedStaticAccessSniff.php

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,13 @@
1818
* (Nested) Static property and constant fetches as well as method calls can be applied to
1919
* any dereferencable expression since PHP 7.0.
2020
*
21+
* Class constants can be dereferenced since PHP 8.0.
22+
*
2123
* PHP version 7.0
24+
* PHP version 8.0
2225
*
2326
* @link https://wiki.php.net/rfc/uniform_variable_syntax
27+
* @link https://wiki.php.net/rfc/variable_syntax_tweaks#class_constant_dereferencability
2428
*
2529
* @since 10.0.0
2630
*/
@@ -64,7 +68,8 @@ public function register()
6468
*/
6569
public function process(File $phpcsFile, $stackPtr)
6670
{
67-
if ($this->supportsBelow('5.6') === false) {
71+
// PHP 8.0 supports both nested static access and class constant dereferencing
72+
if ($this->supportsBelow('7.4') === false) {
6873
return;
6974
}
7075

@@ -122,19 +127,27 @@ public function process(File $phpcsFile, $stackPtr)
122127
return;
123128
}
124129

125-
// Ignore the one form of nested static access which is still not supported: ?::CONST::?.
130+
// Class constants cannot be dereferenced before PHP 8.0.
126131
if ($seenBrackets === false
127132
&& $tokens[$prev]['code'] === \T_STRING
128133
&& $tokens[$prevOperator]['code'] === \T_DOUBLE_COLON
134+
&& $this->supportsBelow('7.4') === true
129135
) {
136+
$phpcsFile->addError(
137+
'Class constants cannot be dereferenced in PHP 7.4 or earlier.',
138+
$stackPtr,
139+
'Found'
140+
);
130141
return;
131142
}
132143

133144
// This is nested static access.
134-
$phpcsFile->addError(
135-
'Nested access to static properties, constants and methods was not supported in PHP 5.6 or earlier.',
136-
$stackPtr,
137-
'Found'
138-
);
145+
if ($this->supportsBelow('5.6') === true) {
146+
$phpcsFile->addError(
147+
'Nested access to static properties, constants and methods was not supported in PHP 5.6 or earlier.',
148+
$stackPtr,
149+
'Found'
150+
);
151+
}
139152
}
140153
}

PHPCompatibility/Tests/Syntax/NewNestedStaticAccessUnitTest.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ echo ($foo->bar())::baz();
3030
// Parse error in any PHP version. Outside the scope of this sniff.
3131
echo $bar::($foo['bar'])::$baz;
3232

33-
// Still not supported.
33+
// PHP 8.0: class constant dereferencing
3434
self::MY_CONSTANT::$baz;
3535
Foo::MY_CONSTANT::$baz;
3636

PHPCompatibility/Tests/Syntax/NewNestedStaticAccessUnitTest.php

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,37 @@ public function dataNestedStaticAccess()
6969
}
7070

7171

72+
/**
73+
* testClassConstantDereferencing
74+
*
75+
* @dataProvider dataClassConstantDereferencing
76+
*
77+
* @param int $line The line number.
78+
*
79+
* @return void
80+
*/
81+
public function testClassConstantDereferencing($line)
82+
{
83+
$file = $this->sniffFile(__FILE__, '7.4');
84+
$this->assertError($file, $line, 'Class constants cannot be dereferenced in PHP 7.4 or earlier.');
85+
}
86+
87+
/**
88+
* Data provider.
89+
*
90+
* @see testClassConstantDereferencing()
91+
*
92+
* @return array
93+
*/
94+
public function dataClassConstantDereferencing()
95+
{
96+
return [
97+
[34],
98+
[35],
99+
];
100+
}
101+
102+
72103
/**
73104
* Verify the sniff doesn't throw false positives.
74105
*
@@ -98,8 +129,6 @@ public function dataNoFalsePositives()
98129
[27],
99130
[28],
100131
[31],
101-
[34],
102-
[35],
103132
];
104133
}
105134

@@ -111,7 +140,7 @@ public function dataNoFalsePositives()
111140
*/
112141
public function testNoViolationsInFileOnValidVersion()
113142
{
114-
$file = $this->sniffFile(__FILE__, '7.0');
143+
$file = $this->sniffFile(__FILE__, '8.0');
115144
$this->assertNoViolation($file);
116145
}
117146
}

0 commit comments

Comments
 (0)