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…
Reference in New Issue
Block a user