Skip to content
This repository has been archived by the owner on Apr 23, 2024. It is now read-only.

php8.1: added enums #12

Merged
merged 1 commit into from
Jul 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 99 additions & 0 deletions internal/php8/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
14 changes: 14 additions & 0 deletions internal/php8/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
68 changes: 68 additions & 0 deletions internal/php8/parser_php8_1_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Loading