Skip to content

Commit 106eba3

Browse files
committed
PHP 8.1: Added support for "enum" keyword
1 parent 6296b27 commit 106eba3

File tree

5 files changed

+374
-0
lines changed

5 files changed

+374
-0
lines changed

package.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
119119
<file baseinstalldir="" name="ArrayKeywordTest.php" role="test" />
120120
<file baseinstalldir="" name="AttributesTest.inc" role="test" />
121121
<file baseinstalldir="" name="AttributesTest.php" role="test" />
122+
<file baseinstalldir="" name="BackfillEnumTest.inc" role="test" />
123+
<file baseinstalldir="" name="BackfillEnumTest.php" role="test" />
122124
<file baseinstalldir="" name="BackfillExplicitOctalNotationTest.inc" role="test" />
123125
<file baseinstalldir="" name="BackfillExplicitOctalNotationTest.php" role="test" />
124126
<file baseinstalldir="" name="BackfillFnTokenTest.inc" role="test" />
@@ -2078,6 +2080,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
20782080
<install as="CodeSniffer/Core/Tokenizer/ArrayKeywordTest.inc" name="tests/Core/Tokenizer/ArrayKeywordTest.inc" />
20792081
<install as="CodeSniffer/Core/Tokenizer/AttributesTest.php" name="tests/Core/Tokenizer/AttributesTest.php" />
20802082
<install as="CodeSniffer/Core/Tokenizer/AttributesTest.inc" name="tests/Core/Tokenizer/AttributesTest.inc" />
2083+
<install as="CodeSniffer/Core/Tokenizer/BackfillEnumTest.php" name="tests/Core/Tokenizer/BackfillEnumTest.php" />
2084+
<install as="CodeSniffer/Core/Tokenizer/BackfillEnumTest.inc" name="tests/Core/Tokenizer/BackfillEnumTest.inc" />
20812085
<install as="CodeSniffer/Core/Tokenizer/BackfillExplicitOctalNotationTest.php" name="tests/Core/Tokenizer/BackfillExplicitOctalNotationTest.php" />
20822086
<install as="CodeSniffer/Core/Tokenizer/BackfillExplicitOctalNotationTest.inc" name="tests/Core/Tokenizer/BackfillExplicitOctalNotationTest.inc" />
20832087
<install as="CodeSniffer/Core/Tokenizer/BackfillFnTokenTest.php" name="tests/Core/Tokenizer/BackfillFnTokenTest.php" />
@@ -2172,6 +2176,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
21722176
<install as="CodeSniffer/Core/Tokenizer/ArrayKeywordTest.inc" name="tests/Core/Tokenizer/ArrayKeywordTest.inc" />
21732177
<install as="CodeSniffer/Core/Tokenizer/AttributesTest.php" name="tests/Core/Tokenizer/AttributesTest.php" />
21742178
<install as="CodeSniffer/Core/Tokenizer/AttributesTest.inc" name="tests/Core/Tokenizer/AttributesTest.inc" />
2179+
<install as="CodeSniffer/Core/Tokenizer/BackfillEnumTest.php" name="tests/Core/Tokenizer/BackfillEnumTest.php" />
2180+
<install as="CodeSniffer/Core/Tokenizer/BackfillEnumTest.inc" name="tests/Core/Tokenizer/BackfillEnumTest.inc" />
21752181
<install as="CodeSniffer/Core/Tokenizer/BackfillExplicitOctalNotationTest.php" name="tests/Core/Tokenizer/BackfillExplicitOctalNotationTest.php" />
21762182
<install as="CodeSniffer/Core/Tokenizer/BackfillExplicitOctalNotationTest.inc" name="tests/Core/Tokenizer/BackfillExplicitOctalNotationTest.inc" />
21772183
<install as="CodeSniffer/Core/Tokenizer/BackfillFnTokenTest.php" name="tests/Core/Tokenizer/BackfillFnTokenTest.php" />

src/Tokenizers/PHP.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,13 @@ class PHP extends Tokenizer
152152
'shared' => false,
153153
'with' => [],
154154
],
155+
T_ENUM => [
156+
'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
157+
'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
158+
'strict' => true,
159+
'shared' => false,
160+
'with' => [],
161+
],
155162
T_USE => [
156163
'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
157164
'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
@@ -339,6 +346,7 @@ class PHP extends Tokenizer
339346
T_ENDIF => 5,
340347
T_ENDSWITCH => 9,
341348
T_ENDWHILE => 8,
349+
T_ENUM => 4,
342350
T_EVAL => 4,
343351
T_EXTENDS => 7,
344352
T_FILE => 8,
@@ -467,6 +475,7 @@ class PHP extends Tokenizer
467475
T_CLASS => true,
468476
T_INTERFACE => true,
469477
T_TRAIT => true,
478+
T_ENUM => true,
470479
T_EXTENDS => true,
471480
T_IMPLEMENTS => true,
472481
T_ATTRIBUTE => true,
@@ -894,6 +903,42 @@ protected function tokenize($string)
894903
continue;
895904
}//end if
896905

906+
/*
907+
Enum keyword for PHP < 8.1
908+
*/
909+
910+
if ($tokenIsArray === true
911+
&& $token[0] === T_STRING
912+
&& strtolower($token[1]) === 'enum'
913+
) {
914+
// Get the next non-empty token.
915+
for ($i = ($stackPtr + 1); $i < $numTokens; $i++) {
916+
if (is_array($tokens[$i]) === false
917+
|| isset(Util\Tokens::$emptyTokens[$tokens[$i][0]]) === false
918+
) {
919+
break;
920+
}
921+
}
922+
923+
if (isset($tokens[$i]) === true
924+
&& is_array($tokens[$i]) === true
925+
&& $tokens[$i][0] === T_STRING
926+
) {
927+
$newToken = [];
928+
$newToken['code'] = T_ENUM;
929+
$newToken['type'] = 'T_ENUM';
930+
$newToken['content'] = $token[1];
931+
$finalTokens[$newStackPtr] = $newToken;
932+
933+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
934+
echo "\t\t* token $stackPtr changed from T_STRING to T_ENUM".PHP_EOL;
935+
}
936+
937+
$newStackPtr++;
938+
continue;
939+
}
940+
}//end if
941+
897942
/*
898943
As of PHP 8.0 fully qualified, partially qualified and namespace relative
899944
identifier names are tokenized differently.

src/Util/Tokens.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,10 @@
167167
define('T_READONLY', 'PHPCS_T_READONLY');
168168
}
169169

170+
if (defined('T_ENUM') === false) {
171+
define('T_ENUM', 'PHPCS_T_ENUM');
172+
}
173+
170174
// Tokens used for parsing doc blocks.
171175
define('T_DOC_COMMENT_STAR', 'PHPCS_T_DOC_COMMENT_STAR');
172176
define('T_DOC_COMMENT_WHITESPACE', 'PHPCS_T_DOC_COMMENT_WHITESPACE');
@@ -194,6 +198,7 @@ final class Tokens
194198
T_CLASS => 1000,
195199
T_INTERFACE => 1000,
196200
T_TRAIT => 1000,
201+
T_ENUM => 1000,
197202
T_NAMESPACE => 1000,
198203
T_FUNCTION => 100,
199204
T_CLOSURE => 100,
@@ -419,6 +424,7 @@ final class Tokens
419424
T_ANON_CLASS => T_ANON_CLASS,
420425
T_INTERFACE => T_INTERFACE,
421426
T_TRAIT => T_TRAIT,
427+
T_ENUM => T_ENUM,
422428
T_NAMESPACE => T_NAMESPACE,
423429
T_FUNCTION => T_FUNCTION,
424430
T_CLOSURE => T_CLOSURE,
@@ -633,6 +639,7 @@ final class Tokens
633639
T_ANON_CLASS => T_ANON_CLASS,
634640
T_INTERFACE => T_INTERFACE,
635641
T_TRAIT => T_TRAIT,
642+
T_ENUM => T_ENUM,
636643
];
637644

638645
/**
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php
2+
3+
/* testPureEnum */
4+
enum Foo
5+
{
6+
case SOME_CASE;
7+
}
8+
9+
/* testBackedIntEnum */
10+
enum Boo: int {
11+
case ONE = 1;
12+
case TWO = 1;
13+
}
14+
15+
/* testBackedStringEnum */
16+
enum Hoo: string
17+
{
18+
case ONE = 'one';
19+
case TWO = 'two';
20+
}
21+
22+
/* testComplexEnum */
23+
enum ComplexEnum: int implements SomeInterface
24+
{
25+
use SomeTrait {
26+
traitMethod as enumMethod;
27+
}
28+
29+
const SOME_CONSTANT = true;
30+
31+
case ONE = 1;
32+
33+
public function someMethod(): bool
34+
{
35+
}
36+
}
37+
38+
/* testEnumWithEnumAsClassName */
39+
enum /* testEnumAsClassNameAfterEnumKeyword */ Enum {}
40+
41+
/* testEnumIsCaseInsensitive */
42+
EnUm Enum {}
43+
44+
/* testEnumUsedAsClassName */
45+
class Enum {
46+
/* testEnumUsedAsClassConstantName */
47+
const ENUM = 'enum';
48+
49+
/* testEnumUsedAsMethodName */
50+
public function enum() {
51+
// Do something.
52+
53+
/* testEnumUsedAsPropertyName */
54+
$this->enum = 'foo';
55+
}
56+
}
57+
58+
/* testEnumUsedAsFunctionName */
59+
function enum()
60+
{
61+
}
62+
63+
/* testDeclarationContainingComment */
64+
enum /* comment */ Name
65+
{
66+
case SOME_CASE;
67+
}
68+
69+
/* testEnumUsedAsNamespaceName */
70+
namespace Enum;
71+
/* testEnumUsedAsPartOfNamespaceName */
72+
namespace My\Enum\Collection;
73+
/* testEnumUsedInObjectInitialization */
74+
$obj = new Enum;
75+
/* testEnumAsFunctionCall */
76+
$var = enum($a, $b);
77+
/* testEnumAsFunctionCallWithNamespace */
78+
var = namespace\enum();
79+
/* testClassConstantFetchWithEnumAsClassName */
80+
echo Enum::CONSTANT;
81+
/* testClassConstantFetchWithEnumAsConstantName */
82+
echo ClassName::ENUM;
83+
84+
/* testParseErrorMissingName */
85+
enum {
86+
case SOME_CASE;
87+
}
88+
89+
/* testParseErrorLiveCoding */
90+
// This must be the last test in the file.
91+
enum

0 commit comments

Comments
 (0)