php8.1: added enum (#12)
This commit is contained in:
		
							parent
							
								
									44bbff6073
								
							
						
					
					
						commit
						af394e9eb0
					
				| @ -1152,6 +1152,105 @@ func (b *Builder) NewInterface( | ||||
| 	return iface | ||||
| } | ||||
| 
 | ||||
| func (b *Builder) NewEnumType( | ||||
| 	ColonTkn *token.Token, | ||||
| 	Type ast.Vertex, | ||||
| ) *ReturnType { | ||||
| 	return &ReturnType{ | ||||
| 		ColonTkn: ColonTkn, | ||||
| 		Type:     Type, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (b *Builder) NewEnumExpr( | ||||
| 	AssignTkn *token.Token, | ||||
| 	Expr ast.Vertex, | ||||
| ) *EnumCaseExpr { | ||||
| 	return &EnumCaseExpr{ | ||||
| 		AssignTkn: AssignTkn, | ||||
| 		Expr:      Expr, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (b *Builder) NewEnum( | ||||
| 	AttrGroups []ast.Vertex, | ||||
| 	EnumTkn *token.Token, | ||||
| 	Name *token.Token, | ||||
| 
 | ||||
| 	EnumScalarType ast.Vertex, | ||||
| 
 | ||||
| 	ImplementsList ast.Vertex, | ||||
| 
 | ||||
| 	OpenCurlyBracketTkn *token.Token, | ||||
| 	Stmts []ast.Vertex, | ||||
| 	CloseCurlyBracketTkn *token.Token, | ||||
| ) *ast.StmtEnum { | ||||
| 	var pos *position2.Position | ||||
| 	if AttrGroups != nil { | ||||
| 		pos = b.Pos.NewNodeListTokenPosition(AttrGroups, CloseCurlyBracketTkn) | ||||
| 	} else { | ||||
| 		pos = b.Pos.NewTokensPosition(EnumTkn, CloseCurlyBracketTkn) | ||||
| 	} | ||||
| 
 | ||||
| 	enum := &ast.StmtEnum{ | ||||
| 		Position:             pos, | ||||
| 		AttrGroups:           AttrGroups, | ||||
| 		EnumTkn:              EnumTkn, | ||||
| 		Name:                 b.NewIdentifier(Name), | ||||
| 		OpenCurlyBracketTkn:  OpenCurlyBracketTkn, | ||||
| 		Stmts:                Stmts, | ||||
| 		CloseCurlyBracketTkn: CloseCurlyBracketTkn, | ||||
| 	} | ||||
| 
 | ||||
| 	if EnumScalarType != nil { | ||||
| 		enumType := EnumScalarType.(*ReturnType) | ||||
| 		enum.ColonTkn = enumType.ColonTkn | ||||
| 		enum.Type = enumType.Type | ||||
| 	} | ||||
| 
 | ||||
| 	if ImplementsList != nil { | ||||
| 		enum.ImplementsTkn = ImplementsList.(*ast.StmtClass).ImplementsTkn | ||||
| 		enum.Implements = ImplementsList.(*ast.StmtClass).Implements | ||||
| 		enum.ImplementsSeparatorTkns = ImplementsList.(*ast.StmtClass).ImplementsSeparatorTkns | ||||
| 	} | ||||
| 
 | ||||
| 	return enum | ||||
| } | ||||
| 
 | ||||
| func (b *Builder) NewEnumCase( | ||||
| 	AttrGroups []ast.Vertex, | ||||
| 	CaseTkn *token.Token, | ||||
| 	Name *token.Token, | ||||
| 	Expr ast.Vertex, | ||||
| 	SemiColonTkn *token.Token, | ||||
| ) *ast.EnumCase { | ||||
| 	var equalTkn *token.Token | ||||
| 	var expr ast.Vertex | ||||
| 	if Expr != nil { | ||||
| 		caseExpr := Expr.(*EnumCaseExpr) | ||||
| 		equalTkn = caseExpr.AssignTkn | ||||
| 		expr = caseExpr.Expr | ||||
| 	} | ||||
| 
 | ||||
| 	var pos *position2.Position | ||||
| 
 | ||||
| 	if AttrGroups != nil { | ||||
| 		pos = b.Pos.NewNodeListTokenPosition(AttrGroups, SemiColonTkn) | ||||
| 	} else { | ||||
| 		pos = b.Pos.NewTokensPosition(CaseTkn, SemiColonTkn) | ||||
| 	} | ||||
| 
 | ||||
| 	return &ast.EnumCase{ | ||||
| 		Position:     pos, | ||||
| 		CaseTkn:      CaseTkn, | ||||
| 		AttrGroups:   AttrGroups, | ||||
| 		Name:         b.NewIdentifier(Name), | ||||
| 		EqualTkn:     equalTkn, | ||||
| 		Expr:         expr, | ||||
| 		SemiColonTkn: SemiColonTkn, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (b *Builder) NewFunction( | ||||
| 	AttrGroups []ast.Vertex, | ||||
| 	FunctionTkn *token.Token, | ||||
|  | ||||
| @ -68,6 +68,20 @@ func (n *ArgumentList) GetPosition() *position.Position { | ||||
| 	return n.Position | ||||
| } | ||||
| 
 | ||||
| type EnumCaseExpr struct { | ||||
| 	Position  *position.Position | ||||
| 	AssignTkn *token.Token | ||||
| 	Expr      ast.Vertex | ||||
| } | ||||
| 
 | ||||
| func (n *EnumCaseExpr) Accept(v ast.Visitor) { | ||||
| 	// do nothing | ||||
| } | ||||
| 
 | ||||
| func (n *EnumCaseExpr) GetPosition() *position.Position { | ||||
| 	return n.Position | ||||
| } | ||||
| 
 | ||||
| type ReturnType struct { | ||||
| 	Position *position.Position | ||||
| 	ColonTkn *token.Token | ||||
|  | ||||
| @ -254,3 +254,71 @@ function f(): never {} | ||||
| 
 | ||||
| 	suite.Run() | ||||
| } | ||||
| 
 | ||||
| func TestEnum(t *testing.T) { | ||||
| 	suite := tester.NewParserDumpTestSuite(t) | ||||
| 	suite.UsePHP8() | ||||
| 	suite.Code = `<?php | ||||
| enum A {} | ||||
| enum B implements Bar, Baz { | ||||
| } | ||||
| enum C: int implements Bar {} | ||||
| ` | ||||
| 
 | ||||
| 	suite.Expected = `&ast.Root{ | ||||
| 	Stmts: []ast.Vertex{ | ||||
| 		&ast.StmtEnum{ | ||||
| 			Name: &ast.Identifier{ | ||||
| 				Val: []byte("A"), | ||||
| 			}, | ||||
| 			Stmts: []ast.Vertex{}, | ||||
| 		}, | ||||
| 		&ast.StmtEnum{ | ||||
| 			Name: &ast.Identifier{ | ||||
| 				Val: []byte("B"), | ||||
| 			}, | ||||
| 			Implements: []ast.Vertex{ | ||||
| 				&ast.Name{ | ||||
| 					Parts: []ast.Vertex{ | ||||
| 						&ast.NamePart{ | ||||
| 							Val: []byte("Bar"), | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 				&ast.Name{ | ||||
| 					Parts: []ast.Vertex{ | ||||
| 						&ast.NamePart{ | ||||
| 							Val: []byte("Baz"), | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			Stmts: []ast.Vertex{}, | ||||
| 		}, | ||||
| 		&ast.StmtEnum{ | ||||
| 			Name: &ast.Identifier{ | ||||
| 				Val: []byte("C"), | ||||
| 			}, | ||||
| 			Type: &ast.Name{ | ||||
| 				Parts: []ast.Vertex{ | ||||
| 					&ast.NamePart{ | ||||
| 						Val: []byte("int"), | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			Implements: []ast.Vertex{ | ||||
| 				&ast.Name{ | ||||
| 					Parts: []ast.Vertex{ | ||||
| 						&ast.NamePart{ | ||||
| 							Val: []byte("Bar"), | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			Stmts: []ast.Vertex{}, | ||||
| 		}, | ||||
| 	}, | ||||
| },` | ||||
| 
 | ||||
| 	suite.Run() | ||||
| } | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -161,6 +161,7 @@ import ( | ||||
| %token <token> T_NAME_QUALIFIED | ||||
| %token <token> T_NAME_FULLY_QUALIFIED | ||||
| %token <token> T_READONLY | ||||
| %token <token> T_ENUM | ||||
| %token <token> '"' | ||||
| %token <token> '`' | ||||
| %token <token> '{' | ||||
| @ -284,6 +285,7 @@ import ( | ||||
| %type <node> catch_list catch | ||||
| %type <node> property_modifier | ||||
| %type <node> attribute_decl attribute_group attribute | ||||
| %type <node> enum_declaration_statement enum_case_expr enum_scalar_type | ||||
| 
 | ||||
| %type <node> member_modifier | ||||
| %type <node> foreach_variable | ||||
| @ -322,7 +324,7 @@ reserved_non_modifiers: | ||||
|     | T_THROW {$$=$1} | T_USE {$$=$1} | T_INSTEADOF {$$=$1} | T_GLOBAL {$$=$1} | T_VAR {$$=$1} | T_UNSET {$$=$1} | T_ISSET {$$=$1} | T_EMPTY {$$=$1} | T_CONTINUE {$$=$1} | T_GOTO {$$=$1} | ||||
|     | T_FUNCTION {$$=$1} | T_CONST {$$=$1} | T_RETURN {$$=$1} | T_PRINT {$$=$1} | T_YIELD {$$=$1} | T_LIST {$$=$1} | T_SWITCH {$$=$1} | T_ENDSWITCH {$$=$1} | T_CASE {$$=$1} | T_DEFAULT {$$=$1} | T_BREAK {$$=$1} | ||||
|     | T_ARRAY {$$=$1} | T_CALLABLE {$$=$1} | T_EXTENDS {$$=$1} | T_IMPLEMENTS {$$=$1} | T_NAMESPACE {$$=$1} | T_TRAIT {$$=$1} | T_INTERFACE {$$=$1} | T_CLASS {$$=$1} | ||||
|     | T_CLASS_C {$$=$1} | T_TRAIT_C {$$=$1} | T_FUNC_C {$$=$1} | T_METHOD_C {$$=$1} | T_LINE {$$=$1} | T_FILE {$$=$1} | T_DIR {$$=$1} | T_NS_C {$$=$1} | T_FN {$$=$1} | T_MATCH {$$=$1} | ||||
|     | T_CLASS_C {$$=$1} | T_TRAIT_C {$$=$1} | T_FUNC_C {$$=$1} | T_METHOD_C {$$=$1} | T_LINE {$$=$1} | T_FILE {$$=$1} | T_DIR {$$=$1} | T_NS_C {$$=$1} | T_FN {$$=$1} | T_MATCH {$$=$1} | T_ENUM {$$=$1} | ||||
| ; | ||||
| 
 | ||||
| semi_reserved: | ||||
| @ -422,6 +424,7 @@ top_statement: | ||||
|     |   class_declaration_statement     { $$ = $1 } | ||||
|     |   trait_declaration_statement     { $$ = $1 } | ||||
|     |   interface_declaration_statement { $$ = $1 } | ||||
|     |   enum_declaration_statement      { $$ = $1 } | ||||
|     |   T_HALT_COMPILER '(' ')' ';' | ||||
|             { | ||||
|                 $$ = &ast.StmtHaltCompiler{ | ||||
| @ -540,6 +543,7 @@ inner_statement: | ||||
|     |   class_declaration_statement          { $$ = $1 } | ||||
|     |   trait_declaration_statement          { $$ = $1 } | ||||
|     |   interface_declaration_statement      { $$ = $1 } | ||||
|     |   enum_declaration_statement           { $$ = $1 } | ||||
|     |   T_HALT_COMPILER '(' ')' ';' | ||||
|             { | ||||
|                 $$ = &ast.StmtHaltCompiler{ | ||||
| @ -886,6 +890,20 @@ interface_declaration_statement: | ||||
|             { $$ = yylex.(*Parser).builder.NewInterface($1, $2, $3, $4, $5, $6, $7) } | ||||
| ; | ||||
| 
 | ||||
| enum_declaration_statement: | ||||
|         optional_attributes | ||||
|         T_ENUM T_STRING enum_scalar_type implements_list '{' class_statement_list '}' | ||||
|             { $$ = yylex.(*Parser).builder.NewEnum($1, $2, $3, $4, $5, $6, $7, $8) } | ||||
| ; | ||||
| 
 | ||||
| enum_scalar_type: | ||||
|         /* empty */   { $$ = nil } | ||||
|     |   ':' type      { $$ = yylex.(*Parser).builder.NewEnumType($1, $2) } | ||||
| 
 | ||||
| enum_case_expr: | ||||
|         /* empty */   { $$ = nil } | ||||
|     |   '=' expr      { $$ = yylex.(*Parser).builder.NewEnumExpr($1, $2) } | ||||
| 
 | ||||
| extends_from: | ||||
|         /* empty */ | ||||
|             { | ||||
| @ -1468,6 +1486,8 @@ class_statement: | ||||
| 
 | ||||
|                 $$ = traitUse | ||||
|             } | ||||
|     |   optional_attributes T_CASE T_STRING enum_case_expr ';' | ||||
|             { $$ = yylex.(*Parser).builder.NewEnumCase($1, $2, $3, $4, $5) } | ||||
| ; | ||||
| 
 | ||||
| name_list: | ||||
|  | ||||
							
								
								
									
										11255
									
								
								internal/php8/scanner.go
									
									
									
									
									
								
							
							
						
						
									
										11255
									
								
								internal/php8/scanner.go
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -239,6 +239,7 @@ func (lex *Lexer) Lex() *token.Token { | ||||
|             'endif'i                          => {lex.setTokenPosition(tkn); tok = token.T_ENDIF; fbreak;}; | ||||
|             'endswitch'i                      => {lex.setTokenPosition(tkn); tok = token.T_ENDSWITCH; fbreak;}; | ||||
|             'endwhile'i                       => {lex.setTokenPosition(tkn); tok = token.T_ENDWHILE; fbreak;}; | ||||
|             'enum'i                           => {lex.setTokenPosition(tkn); tok = token.T_ENUM; fbreak;}; | ||||
|             'eval'i                           => {lex.setTokenPosition(tkn); tok = token.T_EVAL; fbreak;}; | ||||
|             'exit'i | 'die'i                  => {lex.setTokenPosition(tkn); tok = token.T_EXIT; fbreak;}; | ||||
|             'extends'i                        => {lex.setTokenPosition(tkn); tok = token.T_EXTENDS; fbreak;}; | ||||
|  | ||||
| @ -155,3 +155,28 @@ func TestNumberStringTokens(t *testing.T) { | ||||
| 	} | ||||
| 	suite.Run() | ||||
| } | ||||
| 
 | ||||
| func TestEnumTokens(t *testing.T) { | ||||
| 	suite := tester.NewLexerTokenStructTestSuite(t) | ||||
| 	suite.UsePHP8() | ||||
| 	suite.Code = "<?php enum A {}" | ||||
| 	suite.Expected = []*token.Token{ | ||||
| 		{ | ||||
| 			ID:    token.T_ENUM, | ||||
| 			Value: []byte("enum"), | ||||
| 		}, | ||||
| 		{ | ||||
| 			ID:    token.T_STRING, | ||||
| 			Value: []byte("A"), | ||||
| 		}, | ||||
| 		{ | ||||
| 			ID:    '{', | ||||
| 			Value: []byte("{"), | ||||
| 		}, | ||||
| 		{ | ||||
| 			ID:    '}', | ||||
| 			Value: []byte("}"), | ||||
| 		}, | ||||
| 	} | ||||
| 	suite.Run() | ||||
| } | ||||
|  | ||||
| @ -21,6 +21,8 @@ type Visitor interface { | ||||
| 	StmtBreak(n *StmtBreak) | ||||
| 	StmtCase(n *StmtCase) | ||||
| 	StmtCatch(n *StmtCatch) | ||||
| 	StmtEnum(n *StmtEnum) | ||||
| 	EnumCase(n *EnumCase) | ||||
| 	StmtClass(n *StmtClass) | ||||
| 	StmtClassConstList(n *StmtClassConstList) | ||||
| 	StmtClassMethod(n *StmtClassMethod) | ||||
|  | ||||
| @ -337,6 +337,49 @@ func (n *StmtCatch) GetPosition() *position.Position { | ||||
| 	return n.Position | ||||
| } | ||||
| 
 | ||||
| // StmtEnum node | ||||
| type StmtEnum struct { | ||||
| 	Position                *position.Position | ||||
| 	AttrGroups              []Vertex | ||||
| 	EnumTkn                 *token.Token | ||||
| 	Name                    Vertex | ||||
| 	ColonTkn                *token.Token | ||||
| 	Type                    Vertex | ||||
| 	ImplementsTkn           *token.Token | ||||
| 	Implements              []Vertex | ||||
| 	ImplementsSeparatorTkns []*token.Token | ||||
| 	OpenCurlyBracketTkn     *token.Token | ||||
| 	Stmts                   []Vertex | ||||
| 	CloseCurlyBracketTkn    *token.Token | ||||
| } | ||||
| 
 | ||||
| func (n *StmtEnum) Accept(v Visitor) { | ||||
| 	v.StmtEnum(n) | ||||
| } | ||||
| 
 | ||||
| func (n *StmtEnum) GetPosition() *position.Position { | ||||
| 	return n.Position | ||||
| } | ||||
| 
 | ||||
| // EnumCase node | ||||
| type EnumCase struct { | ||||
| 	Position     *position.Position | ||||
| 	AttrGroups   []Vertex | ||||
| 	CaseTkn      *token.Token | ||||
| 	Name         Vertex | ||||
| 	EqualTkn     *token.Token | ||||
| 	Expr         Vertex | ||||
| 	SemiColonTkn *token.Token | ||||
| } | ||||
| 
 | ||||
| func (n *EnumCase) Accept(v Visitor) { | ||||
| 	v.EnumCase(n) | ||||
| } | ||||
| 
 | ||||
| func (n *EnumCase) GetPosition() *position.Position { | ||||
| 	return n.Position | ||||
| } | ||||
| 
 | ||||
| // StmtClass node | ||||
| type StmtClass struct { | ||||
| 	Position                *position.Position | ||||
|  | ||||
| @ -151,6 +151,7 @@ const ( | ||||
| 	T_NAME_QUALIFIED | ||||
| 	T_NAME_FULLY_QUALIFIED | ||||
| 	T_READONLY | ||||
| 	T_ENUM | ||||
| ) | ||||
| 
 | ||||
| type Token struct { | ||||
|  | ||||
| @ -153,11 +153,12 @@ func _() { | ||||
| 	_ = x[T_NAME_QUALIFIED-57488] | ||||
| 	_ = x[T_NAME_FULLY_QUALIFIED-57489] | ||||
| 	_ = x[T_READONLY-57490] | ||||
| 	_ = x[T_ENUM-57491] | ||||
| } | ||||
| 
 | ||||
| const _ID_name = "T_INCLUDET_INCLUDE_ONCET_EXITT_IFT_LNUMBERT_DNUMBERT_STRINGT_STRING_VARNAMET_VARIABLET_NUM_STRINGT_INLINE_HTMLT_CHARACTERT_BAD_CHARACTERT_ENCAPSED_AND_WHITESPACET_CONSTANT_ENCAPSED_STRINGT_ECHOT_DOT_WHILET_ENDWHILET_FORT_ENDFORT_FOREACHT_ENDFOREACHT_DECLARET_ENDDECLARET_AST_SWITCHT_ENDSWITCHT_CASET_DEFAULTT_BREAKT_CONTINUET_GOTOT_FUNCTIONT_FNT_CONSTT_RETURNT_TRYT_CATCHT_FINALLYT_THROWT_USET_INSTEADOFT_GLOBALT_VART_UNSETT_ISSETT_EMPTYT_HALT_COMPILERT_CLASST_TRAITT_INTERFACET_EXTENDST_IMPLEMENTST_OBJECT_OPERATORT_DOUBLE_ARROWT_LISTT_ARRAYT_CALLABLET_CLASS_CT_TRAIT_CT_METHOD_CT_FUNC_CT_LINET_FILET_COMMENTT_DOC_COMMENTT_OPEN_TAGT_OPEN_TAG_WITH_ECHOT_CLOSE_TAGT_WHITESPACET_START_HEREDOCT_END_HEREDOCT_DOLLAR_OPEN_CURLY_BRACEST_CURLY_OPENT_PAAMAYIM_NEKUDOTAYIMT_NAMESPACET_NS_CT_DIRT_NS_SEPARATORT_ELLIPSIST_EVALT_REQUIRET_REQUIRE_ONCET_LOGICAL_ORT_LOGICAL_XORT_LOGICAL_ANDT_INSTANCEOFT_NEWT_CLONET_ELSEIFT_ELSET_ENDIFT_PRINTT_YIELDT_STATICT_ABSTRACTT_FINALT_PRIVATET_PROTECTEDT_PUBLICT_INCT_DECT_YIELD_FROMT_INT_CASTT_DOUBLE_CASTT_STRING_CASTT_ARRAY_CASTT_OBJECT_CASTT_BOOL_CASTT_UNSET_CASTT_COALESCET_SPACESHIPT_NOELSET_PLUS_EQUALT_MINUS_EQUALT_MUL_EQUALT_POW_EQUALT_DIV_EQUALT_CONCAT_EQUALT_MOD_EQUALT_AND_EQUALT_OR_EQUALT_XOR_EQUALT_SL_EQUALT_SR_EQUALT_COALESCE_EQUALT_BOOLEAN_ORT_BOOLEAN_ANDT_POWT_SLT_SRT_IS_IDENTICALT_IS_NOT_IDENTICALT_IS_EQUALT_IS_NOT_EQUALT_IS_SMALLER_OR_EQUALT_IS_GREATER_OR_EQUALT_NULLSAFE_OBJECT_OPERATORT_MATCHT_ATTRIBUTET_NAME_RELATIVET_NAME_QUALIFIEDT_NAME_FULLY_QUALIFIEDT_READONLY" | ||||
| const _ID_name = "T_INCLUDET_INCLUDE_ONCET_EXITT_IFT_LNUMBERT_DNUMBERT_STRINGT_STRING_VARNAMET_VARIABLET_NUM_STRINGT_INLINE_HTMLT_CHARACTERT_BAD_CHARACTERT_ENCAPSED_AND_WHITESPACET_CONSTANT_ENCAPSED_STRINGT_ECHOT_DOT_WHILET_ENDWHILET_FORT_ENDFORT_FOREACHT_ENDFOREACHT_DECLARET_ENDDECLARET_AST_SWITCHT_ENDSWITCHT_CASET_DEFAULTT_BREAKT_CONTINUET_GOTOT_FUNCTIONT_FNT_CONSTT_RETURNT_TRYT_CATCHT_FINALLYT_THROWT_USET_INSTEADOFT_GLOBALT_VART_UNSETT_ISSETT_EMPTYT_HALT_COMPILERT_CLASST_TRAITT_INTERFACET_EXTENDST_IMPLEMENTST_OBJECT_OPERATORT_DOUBLE_ARROWT_LISTT_ARRAYT_CALLABLET_CLASS_CT_TRAIT_CT_METHOD_CT_FUNC_CT_LINET_FILET_COMMENTT_DOC_COMMENTT_OPEN_TAGT_OPEN_TAG_WITH_ECHOT_CLOSE_TAGT_WHITESPACET_START_HEREDOCT_END_HEREDOCT_DOLLAR_OPEN_CURLY_BRACEST_CURLY_OPENT_PAAMAYIM_NEKUDOTAYIMT_NAMESPACET_NS_CT_DIRT_NS_SEPARATORT_ELLIPSIST_EVALT_REQUIRET_REQUIRE_ONCET_LOGICAL_ORT_LOGICAL_XORT_LOGICAL_ANDT_INSTANCEOFT_NEWT_CLONET_ELSEIFT_ELSET_ENDIFT_PRINTT_YIELDT_STATICT_ABSTRACTT_FINALT_PRIVATET_PROTECTEDT_PUBLICT_INCT_DECT_YIELD_FROMT_INT_CASTT_DOUBLE_CASTT_STRING_CASTT_ARRAY_CASTT_OBJECT_CASTT_BOOL_CASTT_UNSET_CASTT_COALESCET_SPACESHIPT_NOELSET_PLUS_EQUALT_MINUS_EQUALT_MUL_EQUALT_POW_EQUALT_DIV_EQUALT_CONCAT_EQUALT_MOD_EQUALT_AND_EQUALT_OR_EQUALT_XOR_EQUALT_SL_EQUALT_SR_EQUALT_COALESCE_EQUALT_BOOLEAN_ORT_BOOLEAN_ANDT_POWT_SLT_SRT_IS_IDENTICALT_IS_NOT_IDENTICALT_IS_EQUALT_IS_NOT_EQUALT_IS_SMALLER_OR_EQUALT_IS_GREATER_OR_EQUALT_NULLSAFE_OBJECT_OPERATORT_MATCHT_ATTRIBUTET_NAME_RELATIVET_NAME_QUALIFIEDT_NAME_FULLY_QUALIFIEDT_READONLYT_ENUM" | ||||
| 
 | ||||
| var _ID_index = [...]uint16{0, 9, 23, 29, 33, 42, 51, 59, 75, 85, 97, 110, 121, 136, 161, 187, 193, 197, 204, 214, 219, 227, 236, 248, 257, 269, 273, 281, 292, 298, 307, 314, 324, 330, 340, 344, 351, 359, 364, 371, 380, 387, 392, 403, 411, 416, 423, 430, 437, 452, 459, 466, 477, 486, 498, 515, 529, 535, 542, 552, 561, 570, 580, 588, 594, 600, 609, 622, 632, 652, 663, 675, 690, 703, 729, 741, 763, 774, 780, 785, 799, 809, 815, 824, 838, 850, 863, 876, 888, 893, 900, 908, 914, 921, 928, 935, 943, 953, 960, 969, 980, 988, 993, 998, 1010, 1020, 1033, 1046, 1058, 1071, 1082, 1094, 1104, 1115, 1123, 1135, 1148, 1159, 1170, 1181, 1195, 1206, 1217, 1227, 1238, 1248, 1258, 1274, 1286, 1299, 1304, 1308, 1312, 1326, 1344, 1354, 1368, 1389, 1410, 1436, 1443, 1454, 1469, 1485, 1507, 1517} | ||||
| var _ID_index = [...]uint16{0, 9, 23, 29, 33, 42, 51, 59, 75, 85, 97, 110, 121, 136, 161, 187, 193, 197, 204, 214, 219, 227, 236, 248, 257, 269, 273, 281, 292, 298, 307, 314, 324, 330, 340, 344, 351, 359, 364, 371, 380, 387, 392, 403, 411, 416, 423, 430, 437, 452, 459, 466, 477, 486, 498, 515, 529, 535, 542, 552, 561, 570, 580, 588, 594, 600, 609, 622, 632, 652, 663, 675, 690, 703, 729, 741, 763, 774, 780, 785, 799, 809, 815, 824, 838, 850, 863, 876, 888, 893, 900, 908, 914, 921, 928, 935, 943, 953, 960, 969, 980, 988, 993, 998, 1010, 1020, 1033, 1046, 1058, 1071, 1082, 1094, 1104, 1115, 1123, 1135, 1148, 1159, 1170, 1181, 1195, 1206, 1217, 1227, 1238, 1248, 1258, 1274, 1286, 1299, 1304, 1308, 1312, 1326, 1344, 1354, 1368, 1389, 1410, 1436, 1443, 1454, 1469, 1485, 1507, 1517, 1523} | ||||
| 
 | ||||
| func (i ID) String() string { | ||||
| 	i -= 57346 | ||||
|  | ||||
| @ -336,6 +336,43 @@ func (v *Dumper) StmtCatch(n *ast.StmtCatch) { | ||||
| 	v.print(v.indent, "},\n") | ||||
| } | ||||
| 
 | ||||
| func (v *Dumper) StmtEnum(n *ast.StmtEnum) { | ||||
| 	v.print(0, "&ast.StmtEnum{\n") | ||||
| 	v.indent++ | ||||
| 
 | ||||
| 	v.dumpPosition(n.Position) | ||||
| 	v.dumpVertexList("AttrGroups", n.AttrGroups) | ||||
| 	v.dumpToken("EnumTkn", n.EnumTkn) | ||||
| 	v.dumpVertex("Name", n.Name) | ||||
| 	v.dumpToken("ColonTkn", n.ColonTkn) | ||||
| 	v.dumpVertex("Type", n.Type) | ||||
| 	v.dumpToken("ImplementsTkn", n.ImplementsTkn) | ||||
| 	v.dumpVertexList("Implements", n.Implements) | ||||
| 	v.dumpTokenList("ImplementsSeparatorTkns", n.ImplementsSeparatorTkns) | ||||
| 	v.dumpToken("OpenCurlyBracketTkn", n.OpenCurlyBracketTkn) | ||||
| 	v.dumpVertexList("Stmts", n.Stmts) | ||||
| 	v.dumpToken("CloseCurlyBracketTkn", n.CloseCurlyBracketTkn) | ||||
| 
 | ||||
| 	v.indent-- | ||||
| 	v.print(v.indent, "},\n") | ||||
| } | ||||
| 
 | ||||
| func (v *Dumper) EnumCase(n *ast.EnumCase) { | ||||
| 	v.print(0, "&ast.EnumCase{\n") | ||||
| 	v.indent++ | ||||
| 
 | ||||
| 	v.dumpPosition(n.Position) | ||||
| 	v.dumpVertexList("AttrGroups", n.AttrGroups) | ||||
| 	v.dumpToken("CaseTkn", n.CaseTkn) | ||||
| 	v.dumpVertex("Name", n.Name) | ||||
| 	v.dumpToken("EqualTkn", n.EqualTkn) | ||||
| 	v.dumpVertex("Expr", n.Expr) | ||||
| 	v.dumpToken("SemiColonTkn", n.SemiColonTkn) | ||||
| 
 | ||||
| 	v.indent-- | ||||
| 	v.print(v.indent, "},\n") | ||||
| } | ||||
| 
 | ||||
| func (v *Dumper) StmtClass(n *ast.StmtClass) { | ||||
| 	v.print(0, "&ast.StmtClass{\n") | ||||
| 	v.indent++ | ||||
|  | ||||
| @ -318,7 +318,65 @@ func (f *formatter) StmtCatch(n *ast.StmtCatch) { | ||||
| 	n.CloseCurlyBracketTkn = f.newToken('}', []byte("}")) | ||||
| } | ||||
| 
 | ||||
| func (f *formatter) StmtEnum(n *ast.StmtEnum) { | ||||
| 	for _, m := range n.AttrGroups { | ||||
| 		m.Accept(f) | ||||
| 		f.addFreeFloating(token.T_WHITESPACE, []byte(" ")) | ||||
| 	} | ||||
| 
 | ||||
| 	n.EnumTkn = f.newToken(token.T_CLASS, []byte("enum")) | ||||
| 
 | ||||
| 	f.addFreeFloating(token.T_WHITESPACE, []byte(" ")) | ||||
| 	n.Name.Accept(f) | ||||
| 
 | ||||
| 	n.ColonTkn = f.newToken(':', []byte(":")) | ||||
| 	n.Type.Accept(f) | ||||
| 
 | ||||
| 	f.addFreeFloating(token.T_WHITESPACE, []byte(" ")) | ||||
| 
 | ||||
| 	if n.Implements != nil { | ||||
| 		n.ImplementsTkn = f.newToken(token.T_IMPLEMENTS, []byte("implements")) | ||||
| 		n.ImplementsSeparatorTkns = f.formatList(n.Implements, ',') | ||||
| 		f.addFreeFloating(token.T_WHITESPACE, []byte(" ")) | ||||
| 	} | ||||
| 
 | ||||
| 	n.OpenCurlyBracketTkn = f.newToken('{', []byte("{")) | ||||
| 
 | ||||
| 	if len(n.Stmts) > 0 { | ||||
| 		f.indent++ | ||||
| 		f.formatStmts(&n.Stmts) | ||||
| 		f.indent-- | ||||
| 
 | ||||
| 		f.addFreeFloating(token.T_WHITESPACE, []byte("\n")) | ||||
| 		f.addIndent() | ||||
| 	} | ||||
| 
 | ||||
| 	n.CloseCurlyBracketTkn = f.newToken('}', []byte("}")) | ||||
| } | ||||
| 
 | ||||
| func (f *formatter) EnumCase(n *ast.EnumCase) { | ||||
| 	for _, m := range n.AttrGroups { | ||||
| 		m.Accept(f) | ||||
| 		f.addFreeFloating(token.T_WHITESPACE, []byte(" ")) | ||||
| 	} | ||||
| 
 | ||||
| 	n.CaseTkn = f.newToken(token.T_CASE, []byte("case")) | ||||
| 
 | ||||
| 	f.addFreeFloating(token.T_WHITESPACE, []byte(" ")) | ||||
| 	n.Name.Accept(f) | ||||
| 
 | ||||
| 	n.EqualTkn = f.newToken('=', []byte("=")) | ||||
| 	n.Expr.Accept(f) | ||||
| 
 | ||||
| 	n.SemiColonTkn = f.newToken(';', []byte(";")) | ||||
| } | ||||
| 
 | ||||
| func (f *formatter) StmtClass(n *ast.StmtClass) { | ||||
| 	for _, m := range n.AttrGroups { | ||||
| 		m.Accept(f) | ||||
| 		f.addFreeFloating(token.T_WHITESPACE, []byte(" ")) | ||||
| 	} | ||||
| 
 | ||||
| 	for _, m := range n.Modifiers { | ||||
| 		m.Accept(f) | ||||
| 		f.addFreeFloating(token.T_WHITESPACE, []byte(" ")) | ||||
|  | ||||
| @ -70,6 +70,14 @@ func (v *Null) StmtCatch(_ *ast.StmtCatch) { | ||||
| 	// do nothing | ||||
| } | ||||
| 
 | ||||
| func (v *Null) StmtEnum(_ *ast.StmtEnum) { | ||||
| 	// do nothing | ||||
| } | ||||
| 
 | ||||
| func (v *Null) EnumCase(_ *ast.EnumCase) { | ||||
| 	// do nothing | ||||
| } | ||||
| 
 | ||||
| func (v *Null) StmtClass(_ *ast.StmtClass) { | ||||
| 	// do nothing | ||||
| } | ||||
|  | ||||
| @ -234,6 +234,28 @@ func (p *printer) StmtClass(n *ast.StmtClass) { | ||||
| 	p.printToken(n.CloseCurlyBracketTkn, []byte("}")) | ||||
| } | ||||
| 
 | ||||
| func (p *printer) StmtEnum(n *ast.StmtEnum) { | ||||
| 	p.printList(n.AttrGroups) | ||||
| 	p.printToken(n.EnumTkn, []byte("enum")) | ||||
| 	p.printNode(n.Name) | ||||
| 	p.printToken(n.ColonTkn, nil) | ||||
| 	p.printNode(n.Type) | ||||
| 	p.printToken(n.ImplementsTkn, p.ifNodeList(n.Implements, []byte("implements"))) | ||||
| 	p.printSeparatedList(n.Implements, n.ImplementsSeparatorTkns, []byte(",")) | ||||
| 	p.printToken(n.OpenCurlyBracketTkn, []byte("{")) | ||||
| 	p.printList(n.Stmts) | ||||
| 	p.printToken(n.CloseCurlyBracketTkn, []byte("}")) | ||||
| } | ||||
| 
 | ||||
| func (p *printer) EnumCase(n *ast.EnumCase) { | ||||
| 	p.printList(n.AttrGroups) | ||||
| 	p.printToken(n.CaseTkn, []byte("case")) | ||||
| 	p.printNode(n.Name) | ||||
| 	p.printToken(n.EqualTkn, nil) | ||||
| 	p.printNode(n.Expr) | ||||
| 	p.printToken(n.SemiColonTkn, []byte(";")) | ||||
| } | ||||
| 
 | ||||
| func (p *printer) StmtClassConstList(n *ast.StmtClassConstList) { | ||||
| 	p.printList(n.AttrGroups) | ||||
| 	p.printList(n.Modifiers) | ||||
|  | ||||
| @ -40,3 +40,37 @@ echo 0o10; | ||||
| echo 0O10; | ||||
| `) | ||||
| } | ||||
| 
 | ||||
| func TestEnumPHP81(t *testing.T) { | ||||
| 	tester.NewParserPrintTestSuite(t).UsePHP8().Run(`<?php | ||||
| enum A { | ||||
|   case B; | ||||
|   case B = 100; | ||||
|   case C = "aa"; | ||||
|   case  | ||||
| 	D; | ||||
| } | ||||
| 
 | ||||
| enum A: int { | ||||
|   case B; | ||||
|   case B = 100; | ||||
| 
 | ||||
|   #[Attribute] | ||||
|   case C = 100; | ||||
| 
 | ||||
|   #[Attribute1] | ||||
|   #[Attribute2] | ||||
|   case D; | ||||
| } | ||||
| 
 | ||||
| enum A implements B { | ||||
|   case C; | ||||
|   public function f(): string {} | ||||
| } | ||||
| 
 | ||||
| enum A implements B, C, D { | ||||
|   case E; | ||||
|   public function f(): string {} | ||||
| } | ||||
| `) | ||||
| } | ||||
|  | ||||
| @ -122,6 +122,33 @@ func (t *Traverser) StmtCatch(n *ast.StmtCatch) { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (t *Traverser) StmtEnum(n *ast.StmtEnum) { | ||||
| 	n.Accept(t.v) | ||||
| 
 | ||||
| 	for _, nn := range n.AttrGroups { | ||||
| 		nn.Accept(t) | ||||
| 	} | ||||
| 	t.Traverse(n.Name) | ||||
| 	t.Traverse(n.Type) | ||||
| 
 | ||||
| 	for _, nn := range n.Implements { | ||||
| 		nn.Accept(t) | ||||
| 	} | ||||
| 	for _, nn := range n.Stmts { | ||||
| 		nn.Accept(t) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (t *Traverser) EnumCase(n *ast.EnumCase) { | ||||
| 	n.Accept(t.v) | ||||
| 
 | ||||
| 	for _, nn := range n.AttrGroups { | ||||
| 		nn.Accept(t) | ||||
| 	} | ||||
| 	t.Traverse(n.Name) | ||||
| 	t.Traverse(n.Expr) | ||||
| } | ||||
| 
 | ||||
| func (t *Traverser) StmtClass(n *ast.StmtClass) { | ||||
| 	n.Accept(t.v) | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user