Skip to content

Commit f236c6a

Browse files
committed
PHP 8.1: Added support for "enum" keyword
1 parent cfdc6c9 commit f236c6a

File tree

7 files changed

+390
-0
lines changed

7 files changed

+390
-0
lines changed

package.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
131131
<file baseinstalldir="" name="ArrayKeywordTest.php" role="test" />
132132
<file baseinstalldir="" name="AttributesTest.inc" role="test" />
133133
<file baseinstalldir="" name="AttributesTest.php" role="test" />
134+
<file baseinstalldir="" name="BackfillEnumTest.inc" role="test" />
135+
<file baseinstalldir="" name="BackfillEnumTest.php" role="test" />
134136
<file baseinstalldir="" name="BackfillExplicitOctalNotationTest.inc" role="test" />
135137
<file baseinstalldir="" name="BackfillExplicitOctalNotationTest.php" role="test" />
136138
<file baseinstalldir="" name="BackfillFnTokenTest.inc" role="test" />
@@ -2092,6 +2094,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
20922094
<install as="CodeSniffer/Core/Tokenizer/ArrayKeywordTest.inc" name="tests/Core/Tokenizer/ArrayKeywordTest.inc" />
20932095
<install as="CodeSniffer/Core/Tokenizer/AttributesTest.php" name="tests/Core/Tokenizer/AttributesTest.php" />
20942096
<install as="CodeSniffer/Core/Tokenizer/AttributesTest.inc" name="tests/Core/Tokenizer/AttributesTest.inc" />
2097+
<install as="CodeSniffer/Core/Tokenizer/BackfillEnumTest.php" name="tests/Core/Tokenizer/BackfillEnumTest.php" />
2098+
<install as="CodeSniffer/Core/Tokenizer/BackfillEnumTest.inc" name="tests/Core/Tokenizer/BackfillEnumTest.inc" />
20952099
<install as="CodeSniffer/Core/Tokenizer/BackfillExplicitOctalNotationTest.php" name="tests/Core/Tokenizer/BackfillExplicitOctalNotationTest.php" />
20962100
<install as="CodeSniffer/Core/Tokenizer/BackfillExplicitOctalNotationTest.inc" name="tests/Core/Tokenizer/BackfillExplicitOctalNotationTest.inc" />
20972101
<install as="CodeSniffer/Core/Tokenizer/BackfillFnTokenTest.php" name="tests/Core/Tokenizer/BackfillFnTokenTest.php" />
@@ -2188,6 +2192,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
21882192
<install as="CodeSniffer/Core/Tokenizer/ArrayKeywordTest.inc" name="tests/Core/Tokenizer/ArrayKeywordTest.inc" />
21892193
<install as="CodeSniffer/Core/Tokenizer/AttributesTest.php" name="tests/Core/Tokenizer/AttributesTest.php" />
21902194
<install as="CodeSniffer/Core/Tokenizer/AttributesTest.inc" name="tests/Core/Tokenizer/AttributesTest.inc" />
2195+
<install as="CodeSniffer/Core/Tokenizer/BackfillEnumTest.php" name="tests/Core/Tokenizer/BackfillEnumTest.php" />
2196+
<install as="CodeSniffer/Core/Tokenizer/BackfillEnumTest.inc" name="tests/Core/Tokenizer/BackfillEnumTest.inc" />
21912197
<install as="CodeSniffer/Core/Tokenizer/BackfillExplicitOctalNotationTest.php" name="tests/Core/Tokenizer/BackfillExplicitOctalNotationTest.php" />
21922198
<install as="CodeSniffer/Core/Tokenizer/BackfillExplicitOctalNotationTest.inc" name="tests/Core/Tokenizer/BackfillExplicitOctalNotationTest.inc" />
21932199
<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,
@@ -952,6 +961,42 @@ protected function tokenize($string)
952961
continue;
953962
}//end if
954963

964+
/*
965+
Enum keyword for PHP < 8.1
966+
*/
967+
968+
if ($tokenIsArray === true
969+
&& $token[0] === T_STRING
970+
&& strtolower($token[1]) === 'enum'
971+
) {
972+
// Get the next non-empty token.
973+
for ($i = ($stackPtr + 1); $i < $numTokens; $i++) {
974+
if (is_array($tokens[$i]) === false
975+
|| isset(Util\Tokens::$emptyTokens[$tokens[$i][0]]) === false
976+
) {
977+
break;
978+
}
979+
}
980+
981+
if (isset($tokens[$i]) === true
982+
&& is_array($tokens[$i]) === true
983+
&& $tokens[$i][0] === T_STRING
984+
) {
985+
$newToken = [];
986+
$newToken['code'] = T_ENUM;
987+
$newToken['type'] = 'T_ENUM';
988+
$newToken['content'] = $token[1];
989+
$finalTokens[$newStackPtr] = $newToken;
990+
991+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
992+
echo "\t\t* token $stackPtr changed from T_STRING to T_ENUM".PHP_EOL;
993+
}
994+
995+
$newStackPtr++;
996+
continue;
997+
}
998+
}//end if
999+
9551000
/*
9561001
As of PHP 8.0 fully qualified, partially qualified and namespace relative
9571002
identifier names are tokenized differently.

src/Util/Tokens.php

Lines changed: 8 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
/**
@@ -684,6 +691,7 @@ final class Tokens
684691
T_ENDIF => T_ENDIF,
685692
T_ENDSWITCH => T_ENDSWITCH,
686693
T_ENDWHILE => T_ENDWHILE,
694+
T_ENUM => T_ENUM,
687695
T_EXIT => T_EXIT,
688696
T_EXTENDS => T_EXTENDS,
689697
T_FINAL => T_FINAL,
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
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+
enum /* testEnumUsedAsEnumName */ Enum
70+
{
71+
}
72+
73+
/* testEnumUsedAsNamespaceName */
74+
namespace Enum;
75+
/* testEnumUsedAsPartOfNamespaceName */
76+
namespace My\Enum\Collection;
77+
/* testEnumUsedInObjectInitialization */
78+
$obj = new Enum;
79+
/* testEnumAsFunctionCall */
80+
$var = enum($a, $b);
81+
/* testEnumAsFunctionCallWithNamespace */
82+
var = namespace\enum();
83+
/* testClassConstantFetchWithEnumAsClassName */
84+
echo Enum::CONSTANT;
85+
/* testClassConstantFetchWithEnumAsConstantName */
86+
echo ClassName::ENUM;
87+
88+
/* testParseErrorMissingName */
89+
enum {
90+
case SOME_CASE;
91+
}
92+
93+
/* testParseErrorLiveCoding */
94+
// This must be the last test in the file.
95+
enum

0 commit comments

Comments
 (0)