@@ -295,11 +295,8 @@ private function isListTerminator(int $parseContext) {
295295            case  ParseContext::SourceElements:
296296                return  false ;
297297
298-             case  ParseContext::InterfaceMembers:
299-             case  ParseContext::ClassMembers:
298+             case  ParseContext::ClasslikeMembers:
300299            case  ParseContext::BlockStatements:
301-             case  ParseContext::TraitMembers:
302-             case  ParseContext::EnumMembers:
303300                return  $ tokenKind
304301            case  ParseContext::SwitchStatementElements:
305302                return  $ tokenKind$ tokenKind
@@ -345,18 +342,9 @@ private function isValidListElement($context, Token $token) {
345342            case  ParseContext::DeclareStatementElements:
346343                return  $ this isStatementStart ($ token
347344
348-             case  ParseContext::ClassMembers :
345+             case  ParseContext::ClasslikeMembers :
349346                return  $ this isClassMemberDeclarationStart ($ token
350347
351-             case  ParseContext::TraitMembers:
352-                 return  $ this isTraitMemberDeclarationStart ($ token
353- 
354-             case  ParseContext::EnumMembers:
355-                 return  $ this isEnumMemberDeclarationStart ($ token
356- 
357-             case  ParseContext::InterfaceMembers:
358-                 return  $ this isInterfaceMemberDeclarationStart ($ token
359- 
360348            case  ParseContext::SwitchStatementElements:
361349                return 
362350                    $ tokenkind  === TokenKind::CaseKeyword ||
@@ -376,17 +364,8 @@ private function getParseListElementFn($context) {
376364            case  ParseContext::ForeachStatementElements:
377365            case  ParseContext::DeclareStatementElements:
378366                return  $ this parseStatementFn ();
379-             case  ParseContext::ClassMembers:
380-                 return  $ this parseClassElementFn ();
381- 
382-             case  ParseContext::TraitMembers:
383-                 return  $ this parseTraitElementFn ();
384- 
385-             case  ParseContext::InterfaceMembers:
386-                 return  $ this parseInterfaceElementFn ();
387- 
388-             case  ParseContext::EnumMembers:
389-                 return  $ this parseEnumElementFn ();
367+             case  ParseContext::ClasslikeMembers:
368+                 return  $ this parseClasslikeElementFn ();
390369
391370            case  ParseContext::SwitchStatementElements:
392371                return  $ this parseCaseOrDefaultStatement ();
@@ -636,15 +615,19 @@ private function parseStatementFn() {
636615        };
637616    }
638617
639-     private  function  parseClassElementFn () {
618+     private  function  parseClasslikeElementFn () {
640619        return  function  ($ parentNode
641620            $ modifiers$ this parseModifiers ();
642621
643622            $ token$ this getCurrentToken ();
623+             // Note that parsing the wrong type of class element in a classlike is a compile-time error, not a parse error. 
644624            switch  ($ tokenkind ) {
645625                case  TokenKind::ConstKeyword:
646626                    return  $ this parseClassConstDeclaration ($ parentNode$ modifiers
647627
628+                 case  TokenKind::CaseKeyword:
629+                     return  $ this parseEnumCaseDeclaration ($ parentNode
630+ 
648631                case  TokenKind::FunctionKeyword:
649632                    return  $ this parseMethodDeclaration ($ parentNode$ modifiers
650633
@@ -688,14 +671,14 @@ private function parseClassDeclaration($parentNode) : Node {
688671        $ classNodename ->kind  = TokenKind::Name;
689672        $ classNodeclassBaseClause  = $ this parseClassBaseClause ($ classNode
690673        $ classNodeclassInterfaceClause  = $ this parseClassInterfaceClause ($ classNode
691-         $ classNodeclassMembers  = $ this parseClassMembers ($ classNode
674+         $ classNodeclassMembers  = $ this parseClasslikeMembers ($ classNode
692675        return  $ classNode
693676    }
694677
695-     private  function  parseClassMembers ($ parentNodeClassMembersNode 
678+     private  function  parseClasslikeMembers ($ parentNodeClassMembersNode 
696679        $ classMembersnew  ClassMembersNode ();
697680        $ classMembersopenBrace  = $ this eat1 (TokenKind::OpenBraceToken);
698-         $ classMembersclassMemberDeclarations  = $ this parseList ($ classMembersClassMembers );
681+         $ classMembersclassMemberDeclarations  = $ this parseList ($ classMembersClasslikeMembers );
699682        $ classMemberscloseBrace  = $ this eat1 (TokenKind::CloseBraceToken);
700683        $ classMembersparent  = $ parentNode
701684        return  $ classMembers
@@ -741,18 +724,9 @@ private function parseAttributeExpression($parentNode) {
741724     */ 
742725    private  function  parseAttributeStatement ($ parentNode
743726        $ attributeGroups$ this parseAttributeGroups (null );
744-         if  ($ parentNodeinstanceof  ClassMembersNode) {
727+         if  ($ parentNodeinstanceof  ClassMembersNode ||  $ parentNode   instanceof  TraitMembers ||  $ parentNode   instanceof  EnumMembers ||  $ parentNode   instanceof  InterfaceMembers ) {
745728            // Create a class element or a MissingMemberDeclaration 
746-             $ statement$ this parseClassElementFn ()($ parentNode
747-         } elseif  ($ parentNodeinstanceof  TraitMembers) {
748-             // Create a trait element or a MissingMemberDeclaration 
749-             $ statement$ this parseTraitElementFn ()($ parentNode
750-         } elseif  ($ parentNodeinstanceof  EnumMembers) {
751-             // Create a enum element or a MissingMemberDeclaration 
752-             $ statement$ this parseEnumElementFn ()($ parentNode
753-         } elseif  ($ parentNodeinstanceof  InterfaceMembers) {
754-             // Create an interface element or a MissingMemberDeclaration 
755-             $ statement$ this parseInterfaceElementFn ()($ parentNode
729+             $ statement$ this parseClasslikeElementFn ()($ parentNode
756730        } else  {
757731            // Classlikes, anonymous functions, global functions, and arrow functions can have attributes. Global constants cannot. 
758732            if  (in_array ($ this token ->kind , [TokenKind::ClassKeyword, TokenKind::TraitKeyword, TokenKind::InterfaceKeyword, TokenKind::AbstractKeyword, TokenKind::FinalKeyword, TokenKind::FunctionKeyword, TokenKind::FnKeyword, TokenKind::EnumKeyword], true ) ||
@@ -1073,6 +1047,9 @@ private function isClassMemberDeclarationStart(Token $token) {
10731047
10741048            // attributes 
10751049            case  TokenKind::AttributeToken:
1050+ 
1051+             // enum 
1052+             case  TokenKind::CaseKeyword:
10761053                return  true ;
10771054
10781055        }
@@ -1417,7 +1394,7 @@ private function parseStringLiteralExpression2($parentNode): StringLiteral {
14171394                case  TokenKind::DollarOpenBraceToken:
14181395                case  TokenKind::OpenBraceDollarToken:
14191396                    $ expressionchildren [] = $ this eat (TokenKind::DollarOpenBraceToken, TokenKind::OpenBraceDollarToken);
1420-                     /**   
1397+                     /** 
14211398                     * @phpstan-ignore-next-line "Strict comparison using 
14221399                     * === between 403|404 and 408 will always evaluate to 
14231400                     * false" is wrong because those tokens were eaten above 
@@ -3286,7 +3263,7 @@ private function parseObjectCreationExpression($parentNode) {
32863263        $ objectCreationExpressionclassInterfaceClause  = $ this parseClassInterfaceClause ($ objectCreationExpression
32873264
32883265        if  ($ this getCurrentToken ()->kind  === TokenKind::OpenBraceToken) {
3289-             $ objectCreationExpressionclassMembers  = $ this parseClassMembers ($ objectCreationExpression
3266+             $ objectCreationExpressionclassMembers  = $ this parseClasslikeMembers ($ objectCreationExpression
32903267        }
32913268
32923269        return  $ objectCreationExpression
@@ -3474,7 +3451,7 @@ private function parseInterfaceDeclaration($parentNode): InterfaceDeclaration {
34743451    private  function  parseInterfaceMembers ($ parentNodeInterfaceMembers 
34753452        $ interfaceMembersnew  InterfaceMembers ();
34763453        $ interfaceMembersopenBrace  = $ this eat1 (TokenKind::OpenBraceToken);
3477-         $ interfaceMembersinterfaceMemberDeclarations  = $ this parseList ($ interfaceMembersInterfaceMembers );
3454+         $ interfaceMembersinterfaceMemberDeclarations  = $ this parseList ($ interfaceMembersClasslikeMembers );
34783455        $ interfaceMemberscloseBrace  = $ this eat1 (TokenKind::CloseBraceToken);
34793456        $ interfaceMembersparent  = $ parentNode
34803457        return  $ interfaceMembers
@@ -3507,30 +3484,6 @@ private function isInterfaceMemberDeclarationStart(Token $token) {
35073484        return  false ;
35083485    }
35093486
3510-     private  function  parseInterfaceElementFn () {
3511-         return  function  ($ parentNode
3512-             $ modifiers$ this parseModifiers ();
3513- 
3514-             $ token$ this getCurrentToken ();
3515-             switch  ($ tokenkind ) {
3516-                 case  TokenKind::ConstKeyword:
3517-                     return  $ this parseClassConstDeclaration ($ parentNode$ modifiers
3518- 
3519-                 case  TokenKind::FunctionKeyword:
3520-                     return  $ this parseMethodDeclaration ($ parentNode$ modifiers
3521- 
3522-                 case  TokenKind::AttributeToken:
3523-                     return  $ this parseAttributeStatement ($ parentNode
3524- 
3525-                 default :
3526-                     $ missingInterfaceMemberDeclarationnew  MissingMemberDeclaration ();
3527-                     $ missingInterfaceMemberDeclarationparent  = $ parentNode
3528-                     $ missingInterfaceMemberDeclarationmodifiers  = $ modifiers
3529-                     return  $ missingInterfaceMemberDeclaration
3530-             }
3531-         };
3532-     }
3533- 
35343487    private  function  parseInterfaceBaseClause ($ parentNode
35353488        $ interfaceBaseClausenew  InterfaceBaseClause ();
35363489        $ interfaceBaseClauseparent  = $ parentNode
@@ -3657,75 +3610,13 @@ private function parseTraitMembers($parentNode) {
36573610
36583611        $ traitMembersopenBrace  = $ this eat1 (TokenKind::OpenBraceToken);
36593612
3660-         $ traitMemberstraitMemberDeclarations  = $ this parseList ($ traitMembersTraitMembers );
3613+         $ traitMemberstraitMemberDeclarations  = $ this parseList ($ traitMembersClasslikeMembers );
36613614
36623615        $ traitMemberscloseBrace  = $ this eat1 (TokenKind::CloseBraceToken);
36633616
36643617        return  $ traitMembers
36653618    }
36663619
3667-     private  function  isTraitMemberDeclarationStart ($ token
3668-         switch  ($ tokenkind ) {
3669-             // property-declaration 
3670-             case  TokenKind::VariableName:
3671- 
3672-             // modifiers 
3673-             case  TokenKind::PublicKeyword:
3674-             case  TokenKind::ProtectedKeyword:
3675-             case  TokenKind::PrivateKeyword:
3676-             case  TokenKind::VarKeyword:
3677-             case  TokenKind::StaticKeyword:
3678-             case  TokenKind::AbstractKeyword:
3679-             case  TokenKind::FinalKeyword:
3680-             case  TokenKind::ReadonlyKeyword:
3681-             case  TokenKind::ConstKeyword:
3682- 
3683-             // method-declaration 
3684-             case  TokenKind::FunctionKeyword:
3685- 
3686-             // trait-use-clauses 
3687-             case  TokenKind::UseKeyword:
3688- 
3689-             // attributes 
3690-             case  TokenKind::AttributeToken:
3691-                 return  true ;
3692-         }
3693-         return  false ;
3694-     }
3695- 
3696-     private  function  parseTraitElementFn () {
3697-         return  function  ($ parentNode
3698-             $ modifiers$ this parseModifiers ();
3699- 
3700-             $ token$ this getCurrentToken ();
3701-             switch  ($ tokenkind ) {
3702-                 case  TokenKind::ConstKeyword:
3703-                     return  $ this parseClassConstDeclaration ($ parentNode$ modifiers
3704- 
3705-                 case  TokenKind::FunctionKeyword:
3706-                     return  $ this parseMethodDeclaration ($ parentNode$ modifiers
3707- 
3708-                 case  TokenKind::QuestionToken:
3709-                     return  $ this parseRemainingPropertyDeclarationOrMissingMemberDeclaration (
3710-                         $ parentNode
3711-                         $ modifiers
3712-                         $ this eat1 (TokenKind::QuestionToken)
3713-                     );
3714-                 case  TokenKind::VariableName:
3715-                     return  $ this parsePropertyDeclaration ($ parentNode$ modifiers
3716- 
3717-                 case  TokenKind::UseKeyword:
3718-                     return  $ this parseTraitUseClause ($ parentNode
3719- 
3720-                 case  TokenKind::AttributeToken:
3721-                     return  $ this parseAttributeStatement ($ parentNode
3722- 
3723-                 default :
3724-                     return  $ this parseRemainingPropertyDeclarationOrMissingMemberDeclaration ($ parentNode$ modifiers
3725-             }
3726-         };
3727-     }
3728- 
37293620    private  function  parseEnumDeclaration ($ parentNode
37303621        $ enumDeclarationnew  EnumDeclaration ();
37313622        $ enumDeclarationparent  = $ parentNode
@@ -3765,7 +3656,7 @@ private function parseEnumMembers($parentNode) {
37653656
37663657        $ enumMembersopenBrace  = $ this eat1 (TokenKind::OpenBraceToken);
37673658
3768-         $ enumMembersenumMemberDeclarations  = $ this parseList ($ enumMembersEnumMembers );
3659+         $ enumMembersenumMemberDeclarations  = $ this parseList ($ enumMembersClasslikeMembers );
37693660
37703661        $ enumMemberscloseBrace  = $ this eat1 (TokenKind::CloseBraceToken);
37713662
@@ -3799,44 +3690,6 @@ private function isEnumMemberDeclarationStart($token) {
37993690        return  false ;
38003691    }
38013692
3802-     private  function  parseEnumElementFn () {
3803-         return  function  ($ parentNode
3804-             $ modifiers$ this parseModifiers ();
3805- 
3806-             $ token$ this getCurrentToken ();
3807-             switch  ($ tokenkind ) {
3808-                 // TODO: CaseKeyword 
3809-                 case  TokenKind::CaseKeyword:
3810-                     return  $ this parseEnumCaseDeclaration ($ parentNode
3811- 
3812-                 case  TokenKind::ConstKeyword:
3813-                     return  $ this parseClassConstDeclaration ($ parentNode$ modifiers
3814- 
3815-                 case  TokenKind::FunctionKeyword:
3816-                     return  $ this parseMethodDeclaration ($ parentNode$ modifiers
3817- 
3818-                 case  TokenKind::QuestionToken:
3819-                     return  $ this parseRemainingPropertyDeclarationOrMissingMemberDeclaration (
3820-                         $ parentNode
3821-                         $ modifiers
3822-                         $ this eat1 (TokenKind::QuestionToken)
3823-                     );
3824-                 case  TokenKind::VariableName:
3825-                     return  $ this parsePropertyDeclaration ($ parentNode$ modifiers
3826- 
3827-                 case  TokenKind::UseKeyword:
3828-                     return  $ this parseTraitUseClause ($ parentNode
3829- 
3830-                 case  TokenKind::AttributeToken:
3831-                     return  $ this parseAttributeStatement ($ parentNode
3832- 
3833-                 default :
3834-                     return  $ this parseRemainingPropertyDeclarationOrMissingMemberDeclaration ($ parentNode$ modifiers
3835-             }
3836-         };
3837-     }
3838- 
3839- 
38403693    /** 
38413694     * @param Node $parentNode 
38423695     * @param Token[] $modifiers 
0 commit comments