diff --git a/internal/php5/parser_test.go b/internal/php5/parser_test.go index bff1735..b2d3144 100644 --- a/internal/php5/parser_test.go +++ b/internal/php5/parser_test.go @@ -9945,74 +9945,66 @@ func TestStmtClass_ClassExtends(t *testing.T) { }, Value: []byte("foo"), }, - Extends: &ast.StmtClassExtends{ + ExtendsTkn: &token.Token{ + ID: token.T_EXTENDS, + Value: []byte("extends"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 19, - EndPos: 30, + EndPos: 26, }, - ExtendTkn: &token.Token{ - ID: token.T_EXTENDS, - Value: []byte("extends"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 19, - EndPos: 26, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 18, - EndPos: 19, - }, + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 18, + EndPos: 19, }, }, }, - ClassName: &ast.NameName{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 27, - EndPos: 30, - }, - Parts: []ast.Vertex{ - &ast.NameNamePart{ + }, + Extends: &ast.NameName{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 27, + EndPos: 30, + }, + Parts: []ast.Vertex{ + &ast.NameNamePart{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 27, + EndPos: 30, + }, + StringTkn: &token.Token{ + ID: token.T_STRING, + Value: []byte("bar"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 27, EndPos: 30, }, - StringTkn: &token.Token{ - ID: token.T_STRING, - Value: []byte("bar"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 27, - EndPos: 30, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 26, - EndPos: 27, - }, + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 26, + EndPos: 27, }, }, }, - Value: []byte("bar"), }, + Value: []byte("bar"), }, }, }, @@ -10187,75 +10179,67 @@ func TestStmtClass_ClassImplement(t *testing.T) { }, Value: []byte("foo"), }, - Implements: &ast.StmtClassImplements{ + ImplementsTkn: &token.Token{ + ID: token.T_IMPLEMENTS, + Value: []byte("implements"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 19, - EndPos: 33, + EndPos: 29, }, - ImplementsTkn: &token.Token{ - ID: token.T_IMPLEMENTS, - Value: []byte("implements"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 19, - EndPos: 29, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 18, - EndPos: 19, - }, - }, - }, - }, - InterfaceNames: []ast.Vertex{ - &ast.NameName{ + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), Position: &position.Position{ StartLine: 1, EndLine: 1, - StartPos: 30, - EndPos: 33, + StartPos: 18, + EndPos: 19, }, - Parts: []ast.Vertex{ - &ast.NameNamePart{ + }, + }, + }, + Implements: []ast.Vertex{ + &ast.NameName{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 30, + EndPos: 33, + }, + Parts: []ast.Vertex{ + &ast.NameNamePart{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 30, + EndPos: 33, + }, + StringTkn: &token.Token{ + ID: token.T_STRING, + Value: []byte("bar"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 30, EndPos: 33, }, - StringTkn: &token.Token{ - ID: token.T_STRING, - Value: []byte("bar"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 30, - EndPos: 33, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 29, - EndPos: 30, - }, + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 29, + EndPos: 30, }, }, }, - Value: []byte("bar"), }, + Value: []byte("bar"), }, }, }, @@ -10431,129 +10415,121 @@ func TestStmtClass_ClassImplements(t *testing.T) { }, Value: []byte("foo"), }, - Implements: &ast.StmtClassImplements{ + ImplementsTkn: &token.Token{ + ID: token.T_IMPLEMENTS, + Value: []byte("implements"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 19, - EndPos: 38, + EndPos: 29, }, - ImplementsTkn: &token.Token{ - ID: token.T_IMPLEMENTS, - Value: []byte("implements"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 19, - EndPos: 29, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 18, - EndPos: 19, - }, - }, - }, - }, - InterfaceNames: []ast.Vertex{ - &ast.NameName{ + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), Position: &position.Position{ StartLine: 1, EndLine: 1, - StartPos: 30, - EndPos: 33, + StartPos: 18, + EndPos: 19, }, - Parts: []ast.Vertex{ - &ast.NameNamePart{ + }, + }, + }, + Implements: []ast.Vertex{ + &ast.NameName{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 30, + EndPos: 33, + }, + Parts: []ast.Vertex{ + &ast.NameNamePart{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 30, + EndPos: 33, + }, + StringTkn: &token.Token{ + ID: token.T_STRING, + Value: []byte("bar"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 30, EndPos: 33, }, - StringTkn: &token.Token{ - ID: token.T_STRING, - Value: []byte("bar"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 30, - EndPos: 33, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 29, - EndPos: 30, - }, + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 29, + EndPos: 30, }, }, }, - Value: []byte("bar"), }, + Value: []byte("bar"), }, }, - &ast.NameName{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 35, - EndPos: 38, - }, - Parts: []ast.Vertex{ - &ast.NameNamePart{ + }, + &ast.NameName{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 35, + EndPos: 38, + }, + Parts: []ast.Vertex{ + &ast.NameNamePart{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 35, + EndPos: 38, + }, + StringTkn: &token.Token{ + ID: token.T_STRING, + Value: []byte("baz"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 35, EndPos: 38, }, - StringTkn: &token.Token{ - ID: token.T_STRING, - Value: []byte("baz"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 35, - EndPos: 38, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 34, - EndPos: 35, - }, + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 34, + EndPos: 35, }, }, }, - Value: []byte("baz"), }, + Value: []byte("baz"), }, }, }, - SeparatorTkns: []*token.Token{ - { - ID: token.ID(44), - Value: []byte(","), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 33, - EndPos: 34, - }, + }, + ImplementsSeparatorTkns: []*token.Token{ + { + ID: token.ID(44), + Value: []byte(","), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 33, + EndPos: 34, }, }, }, @@ -19076,75 +19052,67 @@ func TestStmtInterface_Extend(t *testing.T) { }, Value: []byte("Foo"), }, - Extends: &ast.StmtInterfaceExtends{ + ExtendsTkn: &token.Token{ + ID: token.T_EXTENDS, + Value: []byte("extends"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 17, - EndPos: 28, + EndPos: 24, }, - ExtendsTkn: &token.Token{ - ID: token.T_EXTENDS, - Value: []byte("extends"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 17, - EndPos: 24, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 16, - EndPos: 17, - }, - }, - }, - }, - InterfaceNames: []ast.Vertex{ - &ast.NameName{ + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), Position: &position.Position{ StartLine: 1, EndLine: 1, - StartPos: 25, - EndPos: 28, + StartPos: 16, + EndPos: 17, }, - Parts: []ast.Vertex{ - &ast.NameNamePart{ + }, + }, + }, + Extends: []ast.Vertex{ + &ast.NameName{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 25, + EndPos: 28, + }, + Parts: []ast.Vertex{ + &ast.NameNamePart{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 25, + EndPos: 28, + }, + StringTkn: &token.Token{ + ID: token.T_STRING, + Value: []byte("Bar"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 25, EndPos: 28, }, - StringTkn: &token.Token{ - ID: token.T_STRING, - Value: []byte("Bar"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 25, - EndPos: 28, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 24, - EndPos: 25, - }, + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 24, + EndPos: 25, }, }, }, - Value: []byte("Bar"), }, + Value: []byte("Bar"), }, }, }, @@ -19275,129 +19243,121 @@ func TestStmtInterface_Extends(t *testing.T) { }, Value: []byte("Foo"), }, - Extends: &ast.StmtInterfaceExtends{ + ExtendsTkn: &token.Token{ + ID: token.T_EXTENDS, + Value: []byte("extends"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 17, - EndPos: 33, + EndPos: 24, }, - ExtendsTkn: &token.Token{ - ID: token.T_EXTENDS, - Value: []byte("extends"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 17, - EndPos: 24, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 16, - EndPos: 17, - }, - }, - }, - }, - InterfaceNames: []ast.Vertex{ - &ast.NameName{ + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), Position: &position.Position{ StartLine: 1, EndLine: 1, - StartPos: 25, - EndPos: 28, + StartPos: 16, + EndPos: 17, }, - Parts: []ast.Vertex{ - &ast.NameNamePart{ + }, + }, + }, + Extends: []ast.Vertex{ + &ast.NameName{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 25, + EndPos: 28, + }, + Parts: []ast.Vertex{ + &ast.NameNamePart{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 25, + EndPos: 28, + }, + StringTkn: &token.Token{ + ID: token.T_STRING, + Value: []byte("Bar"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 25, EndPos: 28, }, - StringTkn: &token.Token{ - ID: token.T_STRING, - Value: []byte("Bar"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 25, - EndPos: 28, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 24, - EndPos: 25, - }, + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 24, + EndPos: 25, }, }, }, - Value: []byte("Bar"), }, + Value: []byte("Bar"), }, }, - &ast.NameName{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 30, - EndPos: 33, - }, - Parts: []ast.Vertex{ - &ast.NameNamePart{ + }, + &ast.NameName{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 30, + EndPos: 33, + }, + Parts: []ast.Vertex{ + &ast.NameNamePart{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 30, + EndPos: 33, + }, + StringTkn: &token.Token{ + ID: token.T_STRING, + Value: []byte("Baz"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 30, EndPos: 33, }, - StringTkn: &token.Token{ - ID: token.T_STRING, - Value: []byte("Baz"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 30, - EndPos: 33, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 29, - EndPos: 30, - }, + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 29, + EndPos: 30, }, }, }, - Value: []byte("Baz"), }, + Value: []byte("Baz"), }, }, }, - SeparatorTkns: []*token.Token{ - { - ID: token.ID(44), - Value: []byte(","), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 28, - EndPos: 29, - }, + }, + ExtendsSeparatorTkns: []*token.Token{ + { + ID: token.ID(44), + Value: []byte(","), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 28, + EndPos: 29, }, }, }, diff --git a/internal/php5/php5.go b/internal/php5/php5.go index 3c7d097..6b818aa 100644 Binary files a/internal/php5/php5.go and b/internal/php5/php5.go differ diff --git a/internal/php5/php5.y b/internal/php5/php5.y index 65e6ed1..b422f9f 100644 --- a/internal/php5/php5.y +++ b/internal/php5/php5.y @@ -1280,36 +1280,55 @@ unticked_class_declaration_statement: { switch n := $1.(type) { case *ast.StmtClass : - n.Position = yylex.(*Parser).builder.NewNodeTokenPosition($1, $7) - n.ClassName = &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($2), + className := &ast.Identifier{ + Position: yylex.(*Parser).builder.NewTokenPosition($2), IdentifierTkn: $2, Value: $2.Value, } - n.Extends = $3 - n.Implements = $4 - n.OpenCurlyBracketTkn = $5 - n.Stmts = $6 + + n.Position = yylex.(*Parser).builder.NewNodeTokenPosition($1, $7) + n.ClassName = className + n.OpenCurlyBracketTkn = $5 + n.Stmts = $6 n.CloseCurlyBracketTkn = $7 + + if $3 != nil { + n.ExtendsTkn = $3.(*ast.StmtClass).ExtendsTkn + n.Extends = $3.(*ast.StmtClass).Extends + } + + if $4 != nil { + n.ImplementsTkn = $4.(*ast.StmtClass).ImplementsTkn + n.Implements = $4.(*ast.StmtClass).Implements + n.ImplementsSeparatorTkns = $4.(*ast.StmtClass).ImplementsSeparatorTkns + } case *ast.StmtTrait : - n.Position = yylex.(*Parser).builder.NewNodeTokenPosition($1, $7) - n.TraitName = &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($2), + traitName := &ast.Identifier{ + Position: yylex.(*Parser).builder.NewTokenPosition($2), IdentifierTkn: $2, Value: $2.Value, } - n.Extends = $3 - n.Implements = $4 - n.OpenCurlyBracketTkn = $5 - n.Stmts = $6 + + n.Position = yylex.(*Parser).builder.NewNodeTokenPosition($1, $7) + n.TraitName = traitName + n.OpenCurlyBracketTkn = $5 + n.Stmts = $6 n.CloseCurlyBracketTkn = $7 + + if $3 != nil { + yylex.(*Parser).errHandlerFunc(errors.NewError("A trait cannot extend a class. Traits can only be composed from other traits with the 'use' keyword", $3.(*ast.StmtClass).Position)) + } + + if $4 != nil { + yylex.(*Parser).errHandlerFunc(errors.NewError("A trait cannot implement an interface", $4.(*ast.StmtClass).Position)) + } } $$ = $1 } | interface_entry T_STRING interface_extends_list '{' class_statement_list '}' { - $$ = &ast.StmtInterface{ + iface := &ast.StmtInterface{ Position: yylex.(*Parser).builder.NewTokensPosition($1, $6), InterfaceTkn: $1, InterfaceName: &ast.Identifier{ @@ -1317,11 +1336,18 @@ unticked_class_declaration_statement: IdentifierTkn: $2, Value: $2.Value, }, - Extends: $3, OpenCurlyBracketTkn: $4, Stmts: $5, CloseCurlyBracketTkn: $6, } + + if $3 != nil { + iface.ExtendsTkn = $3.(*ast.StmtInterface).ExtendsTkn + iface.Extends = $3.(*ast.StmtInterface).Extends + iface.ExtendsSeparatorTkns = $3.(*ast.StmtInterface).ExtendsSeparatorTkns + } + + $$ = iface } ; @@ -1378,10 +1404,10 @@ extends_from: } | T_EXTENDS fully_qualified_class_name { - $$ = &ast.StmtClassExtends{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - ExtendTkn: $1, - ClassName: $2, + $$ = &ast.StmtClass{ + Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), + ExtendsTkn: $1, + Extends: $2, } } ; @@ -1400,11 +1426,11 @@ interface_extends_list: } | T_EXTENDS interface_list { - $$ = &ast.StmtInterfaceExtends{ - Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $2.(*ast.ParserSeparatedList).Items), - ExtendsTkn: $1, - InterfaceNames: $2.(*ast.ParserSeparatedList).Items, - SeparatorTkns: $2.(*ast.ParserSeparatedList).SeparatorTkns, + $$ = &ast.StmtInterface{ + Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $2.(*ast.ParserSeparatedList).Items), + ExtendsTkn: $1, + Extends: $2.(*ast.ParserSeparatedList).Items, + ExtendsSeparatorTkns: $2.(*ast.ParserSeparatedList).SeparatorTkns, }; } ; @@ -1416,11 +1442,11 @@ implements_list: } | T_IMPLEMENTS interface_list { - $$ = &ast.StmtClassImplements{ - Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $2.(*ast.ParserSeparatedList).Items), - ImplementsTkn: $1, - InterfaceNames: $2.(*ast.ParserSeparatedList).Items, - SeparatorTkns: $2.(*ast.ParserSeparatedList).SeparatorTkns, + $$ = &ast.StmtClass{ + Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $2.(*ast.ParserSeparatedList).Items), + ImplementsTkn: $1, + Implements: $2.(*ast.ParserSeparatedList).Items, + ImplementsSeparatorTkns: $2.(*ast.ParserSeparatedList).SeparatorTkns, }; } ; diff --git a/internal/php7/parser_test.go b/internal/php7/parser_test.go index d6ddeac..5b63320 100644 --- a/internal/php7/parser_test.go +++ b/internal/php7/parser_test.go @@ -11108,74 +11108,66 @@ func TestStmtClass_ClassExtends(t *testing.T) { }, Value: []byte("foo"), }, - Extends: &ast.StmtClassExtends{ + ExtendsTkn: &token.Token{ + ID: token.T_EXTENDS, + Value: []byte("extends"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 19, - EndPos: 30, + EndPos: 26, }, - ExtendTkn: &token.Token{ - ID: token.T_EXTENDS, - Value: []byte("extends"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 19, - EndPos: 26, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 18, - EndPos: 19, - }, + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 18, + EndPos: 19, }, }, }, - ClassName: &ast.NameName{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 27, - EndPos: 30, - }, - Parts: []ast.Vertex{ - &ast.NameNamePart{ + }, + Extends: &ast.NameName{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 27, + EndPos: 30, + }, + Parts: []ast.Vertex{ + &ast.NameNamePart{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 27, + EndPos: 30, + }, + StringTkn: &token.Token{ + ID: token.T_STRING, + Value: []byte("bar"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 27, EndPos: 30, }, - StringTkn: &token.Token{ - ID: token.T_STRING, - Value: []byte("bar"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 27, - EndPos: 30, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 26, - EndPos: 27, - }, + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 26, + EndPos: 27, }, }, }, - Value: []byte("bar"), }, + Value: []byte("bar"), }, }, }, @@ -11350,75 +11342,67 @@ func TestStmtClass_ClassImplement(t *testing.T) { }, Value: []byte("foo"), }, - Implements: &ast.StmtClassImplements{ + ImplementsTkn: &token.Token{ + ID: token.T_IMPLEMENTS, + Value: []byte("implements"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 19, - EndPos: 33, + EndPos: 29, }, - ImplementsTkn: &token.Token{ - ID: token.T_IMPLEMENTS, - Value: []byte("implements"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 19, - EndPos: 29, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 18, - EndPos: 19, - }, - }, - }, - }, - InterfaceNames: []ast.Vertex{ - &ast.NameName{ + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), Position: &position.Position{ StartLine: 1, EndLine: 1, - StartPos: 30, - EndPos: 33, + StartPos: 18, + EndPos: 19, }, - Parts: []ast.Vertex{ - &ast.NameNamePart{ + }, + }, + }, + Implements: []ast.Vertex{ + &ast.NameName{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 30, + EndPos: 33, + }, + Parts: []ast.Vertex{ + &ast.NameNamePart{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 30, + EndPos: 33, + }, + StringTkn: &token.Token{ + ID: token.T_STRING, + Value: []byte("bar"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 30, EndPos: 33, }, - StringTkn: &token.Token{ - ID: token.T_STRING, - Value: []byte("bar"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 30, - EndPos: 33, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 29, - EndPos: 30, - }, + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 29, + EndPos: 30, }, }, }, - Value: []byte("bar"), }, + Value: []byte("bar"), }, }, }, @@ -11594,129 +11578,121 @@ func TestStmtClass_ClassImplements(t *testing.T) { }, Value: []byte("foo"), }, - Implements: &ast.StmtClassImplements{ + ImplementsTkn: &token.Token{ + ID: token.T_IMPLEMENTS, + Value: []byte("implements"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 19, - EndPos: 38, + EndPos: 29, }, - ImplementsTkn: &token.Token{ - ID: token.T_IMPLEMENTS, - Value: []byte("implements"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 19, - EndPos: 29, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 18, - EndPos: 19, - }, - }, - }, - }, - InterfaceNames: []ast.Vertex{ - &ast.NameName{ + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), Position: &position.Position{ StartLine: 1, EndLine: 1, - StartPos: 30, - EndPos: 33, + StartPos: 18, + EndPos: 19, }, - Parts: []ast.Vertex{ - &ast.NameNamePart{ + }, + }, + }, + Implements: []ast.Vertex{ + &ast.NameName{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 30, + EndPos: 33, + }, + Parts: []ast.Vertex{ + &ast.NameNamePart{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 30, + EndPos: 33, + }, + StringTkn: &token.Token{ + ID: token.T_STRING, + Value: []byte("bar"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 30, EndPos: 33, }, - StringTkn: &token.Token{ - ID: token.T_STRING, - Value: []byte("bar"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 30, - EndPos: 33, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 29, - EndPos: 30, - }, + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 29, + EndPos: 30, }, }, }, - Value: []byte("bar"), }, + Value: []byte("bar"), }, }, - &ast.NameName{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 35, - EndPos: 38, - }, - Parts: []ast.Vertex{ - &ast.NameNamePart{ + }, + &ast.NameName{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 35, + EndPos: 38, + }, + Parts: []ast.Vertex{ + &ast.NameNamePart{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 35, + EndPos: 38, + }, + StringTkn: &token.Token{ + ID: token.T_STRING, + Value: []byte("baz"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 35, EndPos: 38, }, - StringTkn: &token.Token{ - ID: token.T_STRING, - Value: []byte("baz"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 35, - EndPos: 38, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 34, - EndPos: 35, - }, + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 34, + EndPos: 35, }, }, }, - Value: []byte("baz"), }, + Value: []byte("baz"), }, }, }, - SeparatorTkns: []*token.Token{ - { - ID: token.ID(44), - Value: []byte(","), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 33, - EndPos: 34, - }, + }, + ImplementsSeparatorTkns: []*token.Token{ + { + ID: token.ID(44), + Value: []byte(","), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 33, + EndPos: 34, }, }, }, @@ -11883,58 +11859,115 @@ func TestStmtClass_AnonimousClass(t *testing.T) { EndPos: 14, }, }, - Extends: &ast.StmtClassExtends{ + ExtendsTkn: &token.Token{ + ID: token.T_EXTENDS, + Value: []byte("extends"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 15, - EndPos: 26, + EndPos: 22, }, - ExtendTkn: &token.Token{ - ID: token.T_EXTENDS, - Value: []byte("extends"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 15, - EndPos: 22, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 14, - EndPos: 15, - }, + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 14, + EndPos: 15, }, }, }, - ClassName: &ast.NameName{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 23, - EndPos: 26, - }, - Parts: []ast.Vertex{ - &ast.NameNamePart{ + }, + Extends: &ast.NameName{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 23, + EndPos: 26, + }, + Parts: []ast.Vertex{ + &ast.NameNamePart{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 23, + EndPos: 26, + }, + StringTkn: &token.Token{ + ID: token.T_STRING, + Value: []byte("foo"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 23, EndPos: 26, }, + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 22, + EndPos: 23, + }, + }, + }, + }, + Value: []byte("foo"), + }, + }, + }, + ImplementsTkn: &token.Token{ + ID: token.T_IMPLEMENTS, + Value: []byte("implements"), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 27, + EndPos: 37, + }, + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 26, + EndPos: 27, + }, + }, + }, + }, + Implements: []ast.Vertex{ + &ast.NameName{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 38, + EndPos: 41, + }, + Parts: []ast.Vertex{ + &ast.NameNamePart{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 38, + EndPos: 41, + }, StringTkn: &token.Token{ ID: token.T_STRING, - Value: []byte("foo"), + Value: []byte("bar"), Position: &position.Position{ StartLine: 1, EndLine: 1, - StartPos: 23, - EndPos: 26, + StartPos: 38, + EndPos: 41, }, FreeFloating: []*token.Token{ { @@ -11943,140 +11976,67 @@ func TestStmtClass_AnonimousClass(t *testing.T) { Position: &position.Position{ StartLine: 1, EndLine: 1, - StartPos: 22, - EndPos: 23, + StartPos: 37, + EndPos: 38, }, }, }, }, - Value: []byte("foo"), + Value: []byte("bar"), }, }, }, - }, - Implements: &ast.StmtClassImplements{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 27, - EndPos: 46, - }, - ImplementsTkn: &token.Token{ - ID: token.T_IMPLEMENTS, - Value: []byte("implements"), + &ast.NameName{ Position: &position.Position{ StartLine: 1, EndLine: 1, - StartPos: 27, - EndPos: 37, + StartPos: 43, + EndPos: 46, }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), + Parts: []ast.Vertex{ + &ast.NameNamePart{ Position: &position.Position{ StartLine: 1, EndLine: 1, - StartPos: 26, - EndPos: 27, + StartPos: 43, + EndPos: 46, }, - }, - }, - }, - InterfaceNames: []ast.Vertex{ - &ast.NameName{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 38, - EndPos: 41, - }, - Parts: []ast.Vertex{ - &ast.NameNamePart{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 38, - EndPos: 41, - }, - StringTkn: &token.Token{ - ID: token.T_STRING, - Value: []byte("bar"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 38, - EndPos: 41, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 37, - EndPos: 38, - }, - }, - }, - }, - Value: []byte("bar"), - }, - }, - }, - &ast.NameName{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 43, - EndPos: 46, - }, - Parts: []ast.Vertex{ - &ast.NameNamePart{ + StringTkn: &token.Token{ + ID: token.T_STRING, + Value: []byte("baz"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 43, EndPos: 46, }, - StringTkn: &token.Token{ - ID: token.T_STRING, - Value: []byte("baz"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 43, - EndPos: 46, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 42, - EndPos: 43, - }, + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 42, + EndPos: 43, }, }, }, - Value: []byte("baz"), }, + Value: []byte("baz"), }, }, }, - SeparatorTkns: []*token.Token{ - { - ID: token.ID(44), - Value: []byte(","), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 41, - EndPos: 42, - }, + }, + ImplementsSeparatorTkns: []*token.Token{ + { + ID: token.ID(44), + Value: []byte(","), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 41, + EndPos: 42, }, }, }, @@ -20762,75 +20722,67 @@ func TestStmtInterface_Extend(t *testing.T) { }, Value: []byte("Foo"), }, - Extends: &ast.StmtInterfaceExtends{ + ExtendsTkn: &token.Token{ + ID: token.T_EXTENDS, + Value: []byte("extends"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 17, - EndPos: 28, + EndPos: 24, }, - ExtendsTkn: &token.Token{ - ID: token.T_EXTENDS, - Value: []byte("extends"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 17, - EndPos: 24, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 16, - EndPos: 17, - }, - }, - }, - }, - InterfaceNames: []ast.Vertex{ - &ast.NameName{ + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), Position: &position.Position{ StartLine: 1, EndLine: 1, - StartPos: 25, - EndPos: 28, + StartPos: 16, + EndPos: 17, }, - Parts: []ast.Vertex{ - &ast.NameNamePart{ + }, + }, + }, + Extends: []ast.Vertex{ + &ast.NameName{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 25, + EndPos: 28, + }, + Parts: []ast.Vertex{ + &ast.NameNamePart{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 25, + EndPos: 28, + }, + StringTkn: &token.Token{ + ID: token.T_STRING, + Value: []byte("Bar"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 25, EndPos: 28, }, - StringTkn: &token.Token{ - ID: token.T_STRING, - Value: []byte("Bar"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 25, - EndPos: 28, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 24, - EndPos: 25, - }, + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 24, + EndPos: 25, }, }, }, - Value: []byte("Bar"), }, + Value: []byte("Bar"), }, }, }, @@ -20961,129 +20913,121 @@ func TestStmtInterface_Extends(t *testing.T) { }, Value: []byte("Foo"), }, - Extends: &ast.StmtInterfaceExtends{ + ExtendsTkn: &token.Token{ + ID: token.T_EXTENDS, + Value: []byte("extends"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 17, - EndPos: 33, + EndPos: 24, }, - ExtendsTkn: &token.Token{ - ID: token.T_EXTENDS, - Value: []byte("extends"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 17, - EndPos: 24, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 16, - EndPos: 17, - }, - }, - }, - }, - InterfaceNames: []ast.Vertex{ - &ast.NameName{ + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), Position: &position.Position{ StartLine: 1, EndLine: 1, - StartPos: 25, - EndPos: 28, + StartPos: 16, + EndPos: 17, }, - Parts: []ast.Vertex{ - &ast.NameNamePart{ + }, + }, + }, + Extends: []ast.Vertex{ + &ast.NameName{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 25, + EndPos: 28, + }, + Parts: []ast.Vertex{ + &ast.NameNamePart{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 25, + EndPos: 28, + }, + StringTkn: &token.Token{ + ID: token.T_STRING, + Value: []byte("Bar"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 25, EndPos: 28, }, - StringTkn: &token.Token{ - ID: token.T_STRING, - Value: []byte("Bar"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 25, - EndPos: 28, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 24, - EndPos: 25, - }, + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 24, + EndPos: 25, }, }, }, - Value: []byte("Bar"), }, + Value: []byte("Bar"), }, }, - &ast.NameName{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 30, - EndPos: 33, - }, - Parts: []ast.Vertex{ - &ast.NameNamePart{ + }, + &ast.NameName{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 30, + EndPos: 33, + }, + Parts: []ast.Vertex{ + &ast.NameNamePart{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 30, + EndPos: 33, + }, + StringTkn: &token.Token{ + ID: token.T_STRING, + Value: []byte("Baz"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 30, EndPos: 33, }, - StringTkn: &token.Token{ - ID: token.T_STRING, - Value: []byte("Baz"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 30, - EndPos: 33, - }, - FreeFloating: []*token.Token{ - { - ID: token.T_WHITESPACE, - Value: []byte(" "), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 29, - EndPos: 30, - }, + FreeFloating: []*token.Token{ + { + ID: token.T_WHITESPACE, + Value: []byte(" "), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 29, + EndPos: 30, }, }, }, - Value: []byte("Baz"), }, + Value: []byte("Baz"), }, }, }, - SeparatorTkns: []*token.Token{ - { - ID: token.ID(44), - Value: []byte(","), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 28, - EndPos: 29, - }, + }, + ExtendsSeparatorTkns: []*token.Token{ + { + ID: token.ID(44), + Value: []byte(","), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 28, + EndPos: 29, }, }, }, diff --git a/internal/php7/php7.go b/internal/php7/php7.go index 97c37c1..2c353f7 100644 Binary files a/internal/php7/php7.go and b/internal/php7/php7.go differ diff --git a/internal/php7/php7.y b/internal/php7/php7.y index ec98771..117b1f8 100644 --- a/internal/php7/php7.y +++ b/internal/php7/php7.y @@ -1203,7 +1203,7 @@ is_variadic: class_declaration_statement: class_modifiers T_CLASS T_STRING extends_from implements_list backup_doc_comment '{' class_statement_list '}' { - $$ = &ast.StmtClass{ + class := &ast.StmtClass{ Position: yylex.(*Parser).builder.NewOptionalListTokensPosition($1, $2, $9), Modifiers: $1, ClassTkn: $2, @@ -1212,16 +1212,27 @@ class_declaration_statement: IdentifierTkn: $3, Value: $3.Value, }, - Extends: $4, - Implements: $5, OpenCurlyBracketTkn: $7, Stmts: $8, CloseCurlyBracketTkn: $9, } + + if $4 != nil { + class.ExtendsTkn = $4.(*ast.StmtClass).ExtendsTkn + class.Extends = $4.(*ast.StmtClass).Extends + } + + if $5 != nil { + class.ImplementsTkn = $5.(*ast.StmtClass).ImplementsTkn + class.Implements = $5.(*ast.StmtClass).Implements + class.ImplementsSeparatorTkns = $5.(*ast.StmtClass).ImplementsSeparatorTkns + } + + $$ = class } | T_CLASS T_STRING extends_from implements_list backup_doc_comment '{' class_statement_list '}' { - $$ = &ast.StmtClass{ + class := &ast.StmtClass{ Position: yylex.(*Parser).builder.NewTokensPosition($1, $8), ClassTkn: $1, ClassName: &ast.Identifier{ @@ -1229,12 +1240,23 @@ class_declaration_statement: IdentifierTkn: $2, Value: $2.Value, }, - Extends: $3, - Implements: $4, OpenCurlyBracketTkn: $6, Stmts: $7, CloseCurlyBracketTkn: $8, } + + if $3 != nil { + class.ExtendsTkn = $3.(*ast.StmtClass).ExtendsTkn + class.Extends = $3.(*ast.StmtClass).Extends + } + + if $4 != nil { + class.ImplementsTkn = $4.(*ast.StmtClass).ImplementsTkn + class.Implements = $4.(*ast.StmtClass).Implements + class.ImplementsSeparatorTkns = $4.(*ast.StmtClass).ImplementsSeparatorTkns + } + + $$ = class } ; @@ -1289,7 +1311,7 @@ trait_declaration_statement: interface_declaration_statement: T_INTERFACE T_STRING interface_extends_list backup_doc_comment '{' class_statement_list '}' { - $$ = &ast.StmtInterface{ + iface := &ast.StmtInterface{ Position: yylex.(*Parser).builder.NewTokensPosition($1, $7), InterfaceTkn: $1, InterfaceName: &ast.Identifier{ @@ -1297,11 +1319,18 @@ interface_declaration_statement: IdentifierTkn: $2, Value: $2.Value, }, - Extends: $3, OpenCurlyBracketTkn: $5, Stmts: $6, CloseCurlyBracketTkn: $7, } + + if $3 != nil { + iface.ExtendsTkn = $3.(*ast.StmtInterface).ExtendsTkn + iface.Extends = $3.(*ast.StmtInterface).Extends + iface.ExtendsSeparatorTkns = $3.(*ast.StmtInterface).ExtendsSeparatorTkns + } + + $$ = iface } ; @@ -1312,10 +1341,10 @@ extends_from: } | T_EXTENDS name { - $$ = &ast.StmtClassExtends{ - Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), - ExtendTkn: $1, - ClassName: $2, + $$ = &ast.StmtClass{ + Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), + ExtendsTkn: $1, + Extends: $2, } } ; @@ -1327,11 +1356,11 @@ interface_extends_list: } | T_EXTENDS name_list { - $$ = &ast.StmtInterfaceExtends{ - Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $2.(*ast.ParserSeparatedList).Items), - ExtendsTkn: $1, - InterfaceNames: $2.(*ast.ParserSeparatedList).Items, - SeparatorTkns: $2.(*ast.ParserSeparatedList).SeparatorTkns, + $$ = &ast.StmtInterface{ + Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $2.(*ast.ParserSeparatedList).Items), + ExtendsTkn: $1, + Extends: $2.(*ast.ParserSeparatedList).Items, + ExtendsSeparatorTkns: $2.(*ast.ParserSeparatedList).SeparatorTkns, }; } ; @@ -1343,11 +1372,11 @@ implements_list: } | T_IMPLEMENTS name_list { - $$ = &ast.StmtClassImplements{ - Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $2.(*ast.ParserSeparatedList).Items), - ImplementsTkn: $1, - InterfaceNames: $2.(*ast.ParserSeparatedList).Items, - SeparatorTkns: $2.(*ast.ParserSeparatedList).SeparatorTkns, + $$ = &ast.StmtClass{ + Position: yylex.(*Parser).builder.NewTokenNodeListPosition($1, $2.(*ast.ParserSeparatedList).Items), + ImplementsTkn: $1, + Implements: $2.(*ast.ParserSeparatedList).Items, + ImplementsSeparatorTkns: $2.(*ast.ParserSeparatedList).SeparatorTkns, }; } ; @@ -2458,19 +2487,30 @@ non_empty_for_exprs: anonymous_class: T_CLASS ctor_arguments extends_from implements_list backup_doc_comment '{' class_statement_list '}' { - $$ = &ast.StmtClass{ + class := &ast.StmtClass{ Position: yylex.(*Parser).builder.NewTokensPosition($1, $8), ClassTkn: $1, OpenParenthesisTkn: $2.(*ast.ArgumentList).OpenParenthesisTkn, Arguments: $2.(*ast.ArgumentList).Arguments, SeparatorTkns: $2.(*ast.ArgumentList).SeparatorTkns, CloseParenthesisTkn: $2.(*ast.ArgumentList).CloseParenthesisTkn, - Extends: $3, - Implements: $4, OpenCurlyBracketTkn: $6, Stmts: $7, CloseCurlyBracketTkn: $8, } + + if $3 != nil { + class.ExtendsTkn = $3.(*ast.StmtClass).ExtendsTkn + class.Extends = $3.(*ast.StmtClass).Extends + } + + if $4 != nil { + class.ImplementsTkn = $4.(*ast.StmtClass).ImplementsTkn + class.Implements = $4.(*ast.StmtClass).Implements + class.ImplementsSeparatorTkns = $4.(*ast.StmtClass).ImplementsSeparatorTkns + } + + $$ = class } ; diff --git a/pkg/ast/ast.go b/pkg/ast/ast.go index 508cca0..d8fb966 100644 --- a/pkg/ast/ast.go +++ b/pkg/ast/ast.go @@ -31,8 +31,6 @@ type NodeVisitor interface { StmtCatch(n *StmtCatch) StmtClass(n *StmtClass) StmtClassConstList(n *StmtClassConstList) - StmtClassExtends(n *StmtClassExtends) - StmtClassImplements(n *StmtClassImplements) StmtClassMethod(n *StmtClassMethod) StmtConstList(n *StmtConstList) StmtConstant(n *StmtConstant) @@ -54,7 +52,6 @@ type NodeVisitor interface { StmtIf(n *StmtIf) StmtInlineHtml(n *StmtInlineHtml) StmtInterface(n *StmtInterface) - StmtInterfaceExtends(n *StmtInterfaceExtends) StmtLabel(n *StmtLabel) StmtNamespace(n *StmtNamespace) StmtNop(n *StmtNop) diff --git a/pkg/ast/node.go b/pkg/ast/node.go index d523b27..98889da 100644 --- a/pkg/ast/node.go +++ b/pkg/ast/node.go @@ -285,19 +285,22 @@ func (n *StmtCatch) GetPosition() *position.Position { // StmtClass node type StmtClass struct { - Position *position.Position - Modifiers []Vertex - ClassTkn *token.Token - ClassName Vertex - OpenParenthesisTkn *token.Token - Arguments []Vertex - SeparatorTkns []*token.Token - CloseParenthesisTkn *token.Token - Extends Vertex - Implements Vertex - OpenCurlyBracketTkn *token.Token - Stmts []Vertex - CloseCurlyBracketTkn *token.Token + Position *position.Position + Modifiers []Vertex + ClassTkn *token.Token + ClassName Vertex + OpenParenthesisTkn *token.Token + Arguments []Vertex + SeparatorTkns []*token.Token + CloseParenthesisTkn *token.Token + ExtendsTkn *token.Token + Extends Vertex + ImplementsTkn *token.Token + Implements []Vertex + ImplementsSeparatorTkns []*token.Token + OpenCurlyBracketTkn *token.Token + Stmts []Vertex + CloseCurlyBracketTkn *token.Token } func (n *StmtClass) Accept(v NodeVisitor) { @@ -326,37 +329,6 @@ func (n *StmtClassConstList) GetPosition() *position.Position { return n.Position } -// StmtClassExtends node -type StmtClassExtends struct { - Position *position.Position - ExtendTkn *token.Token - ClassName Vertex -} - -func (n *StmtClassExtends) Accept(v NodeVisitor) { - v.StmtClassExtends(n) -} - -func (n *StmtClassExtends) GetPosition() *position.Position { - return n.Position -} - -// StmtClassImplements node -type StmtClassImplements struct { - Position *position.Position - ImplementsTkn *token.Token - InterfaceNames []Vertex - SeparatorTkns []*token.Token -} - -func (n *StmtClassImplements) Accept(v NodeVisitor) { - v.StmtClassImplements(n) -} - -func (n *StmtClassImplements) GetPosition() *position.Position { - return n.Position -} - // StmtClassMethod node type StmtClassMethod struct { Position *position.Position @@ -744,7 +716,9 @@ type StmtInterface struct { Position *position.Position InterfaceTkn *token.Token InterfaceName Vertex - Extends Vertex + ExtendsTkn *token.Token + Extends []Vertex + ExtendsSeparatorTkns []*token.Token OpenCurlyBracketTkn *token.Token Stmts []Vertex CloseCurlyBracketTkn *token.Token @@ -758,22 +732,6 @@ func (n *StmtInterface) GetPosition() *position.Position { return n.Position } -// StmtInterfaceExtends node -type StmtInterfaceExtends struct { - Position *position.Position - ExtendsTkn *token.Token - InterfaceNames []Vertex - SeparatorTkns []*token.Token -} - -func (n *StmtInterfaceExtends) Accept(v NodeVisitor) { - v.StmtInterfaceExtends(n) -} - -func (n *StmtInterfaceExtends) GetPosition() *position.Position { - return n.Position -} - // StmtLabel node type StmtLabel struct { Position *position.Position @@ -966,8 +924,6 @@ type StmtTrait struct { Position *position.Position TraitTkn *token.Token TraitName Vertex - Extends Vertex - Implements Vertex OpenCurlyBracketTkn *token.Token Stmts []Vertex CloseCurlyBracketTkn *token.Token diff --git a/pkg/ast/traverser/dfs.go b/pkg/ast/traverser/dfs.go index 93333c9..9e58ba5 100644 --- a/pkg/ast/traverser/dfs.go +++ b/pkg/ast/traverser/dfs.go @@ -170,9 +170,11 @@ func (t *DFS) Traverse(n ast.Vertex) { t.visitor.Leave("Extends", true) } if nn.Implements != nil { - t.visitor.Enter("Implements", true) - t.Traverse(nn.Implements) - t.visitor.Leave("Implements", true) + t.visitor.Enter("Implements", false) + for _, c := range nn.Implements { + t.Traverse(c) + } + t.visitor.Leave("Implements", false) } if nn.Stmts != nil { t.visitor.Enter("Stmts", false) @@ -202,32 +204,6 @@ func (t *DFS) Traverse(n ast.Vertex) { } t.visitor.Leave("Consts", false) } - case *ast.StmtClassExtends: - if nn == nil { - return - } - if !t.visitor.EnterNode(nn) { - return - } - if nn.ClassName != nil { - t.visitor.Enter("ClassName", true) - t.Traverse(nn.ClassName) - t.visitor.Leave("ClassName", true) - } - case *ast.StmtClassImplements: - if nn == nil { - return - } - if !t.visitor.EnterNode(nn) { - return - } - if nn.InterfaceNames != nil { - t.visitor.Enter("InterfaceNames", false) - for _, c := range nn.InterfaceNames { - t.Traverse(c) - } - t.visitor.Leave("InterfaceNames", false) - } case *ast.StmtClassMethod: if nn == nil { return @@ -599,9 +575,11 @@ func (t *DFS) Traverse(n ast.Vertex) { t.visitor.Leave("InterfaceName", true) } if nn.Extends != nil { - t.visitor.Enter("Extends", true) - t.Traverse(nn.Extends) - t.visitor.Leave("Extends", true) + t.visitor.Enter("Extends", false) + for _, c := range nn.Extends { + t.Traverse(c) + } + t.visitor.Leave("Extends", false) } if nn.Stmts != nil { t.visitor.Enter("Stmts", false) @@ -610,20 +588,6 @@ func (t *DFS) Traverse(n ast.Vertex) { } t.visitor.Leave("Stmts", false) } - case *ast.StmtInterfaceExtends: - if nn == nil { - return - } - if !t.visitor.EnterNode(nn) { - return - } - if nn.InterfaceNames != nil { - t.visitor.Enter("InterfaceNames", false) - for _, c := range nn.InterfaceNames { - t.Traverse(c) - } - t.visitor.Leave("InterfaceNames", false) - } case *ast.StmtLabel: if nn == nil { return diff --git a/pkg/ast/visitor/dumper.go b/pkg/ast/visitor/dumper.go index 0e1bf41..2783faa 100644 --- a/pkg/ast/visitor/dumper.go +++ b/pkg/ast/visitor/dumper.go @@ -286,8 +286,11 @@ func (v *Dumper) StmtClass(n *ast.StmtClass) { v.dumpVertexList("Arguments", n.Arguments) v.dumpTokenList("SeparatorTkns", n.SeparatorTkns) v.dumpToken("CloseParenthesisTkn", n.CloseParenthesisTkn) + v.dumpToken("ExtendsTkn", n.ExtendsTkn) v.dumpVertex("Extends", n.Extends) - v.dumpVertex("Implements", n.Implements) + 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) @@ -311,31 +314,6 @@ func (v *Dumper) StmtClassConstList(n *ast.StmtClassConstList) { v.print(v.indent, "},\n") } -func (v *Dumper) StmtClassExtends(n *ast.StmtClassExtends) { - v.print(0, "&ast.StmtClassExtends{\n") - v.indent++ - - v.dumpPosition(n.Position) - v.dumpToken("ExtendTkn", n.ExtendTkn) - v.dumpVertex("ClassName", n.ClassName) - - v.indent-- - v.print(v.indent, "},\n") -} - -func (v *Dumper) StmtClassImplements(n *ast.StmtClassImplements) { - v.print(0, "&ast.StmtClassImplements{\n") - v.indent++ - - v.dumpPosition(n.Position) - v.dumpToken("ImplementsTkn", n.ImplementsTkn) - v.dumpVertexList("InterfaceNames", n.InterfaceNames) - v.dumpTokenList("SeparatorTkns", n.SeparatorTkns) - - v.indent-- - v.print(v.indent, "},\n") -} - func (v *Dumper) StmtClassMethod(n *ast.StmtClassMethod) { v.print(0, "&ast.StmtClassMethod{\n") v.indent++ @@ -666,7 +644,9 @@ func (v *Dumper) StmtInterface(n *ast.StmtInterface) { v.dumpPosition(n.Position) v.dumpToken("InterfaceTkn", n.InterfaceTkn) v.dumpVertex("InterfaceName", n.InterfaceName) - v.dumpVertex("Extends", n.Extends) + v.dumpToken("ExtendsTkn", n.ExtendsTkn) + v.dumpVertexList("Extends", n.Extends) + v.dumpTokenList("ExtendsSeparatorTkns", n.ExtendsSeparatorTkns) v.dumpToken("OpenCurlyBracketTkn", n.OpenCurlyBracketTkn) v.dumpVertexList("Stmts", n.Stmts) v.dumpToken("CloseCurlyBracketTkn", n.CloseCurlyBracketTkn) @@ -675,19 +655,6 @@ func (v *Dumper) StmtInterface(n *ast.StmtInterface) { v.print(v.indent, "},\n") } -func (v *Dumper) StmtInterfaceExtends(n *ast.StmtInterfaceExtends) { - v.print(0, "&ast.StmtInterfaceExtends{\n") - v.indent++ - - v.dumpPosition(n.Position) - v.dumpToken("ExtendsTkn", n.ExtendsTkn) - v.dumpVertexList("InterfaceNames", n.InterfaceNames) - v.dumpTokenList("SeparatorTkns", n.SeparatorTkns) - - v.indent-- - v.print(v.indent, "},\n") -} - func (v *Dumper) StmtLabel(n *ast.StmtLabel) { v.print(0, "&ast.StmtLabel{\n") v.indent++ @@ -849,8 +816,6 @@ func (v *Dumper) StmtTrait(n *ast.StmtTrait) { v.dumpPosition(n.Position) v.dumpToken("TraitTkn", n.TraitTkn) v.dumpVertex("TraitName", n.TraitName) - v.dumpVertex("Extends", n.Extends) - v.dumpVertex("Implements", n.Implements) v.dumpToken("OpenCurlyBracketTkn", n.OpenCurlyBracketTkn) v.dumpVertexList("Stmts", n.Stmts) v.dumpToken("CloseCurlyBracketTkn", n.CloseCurlyBracketTkn) diff --git a/pkg/ast/visitor/formatter.go b/pkg/ast/visitor/formatter.go index b81a13c..c6e1a50 100644 --- a/pkg/ast/visitor/formatter.go +++ b/pkg/ast/visitor/formatter.go @@ -281,12 +281,14 @@ func (f *formatter) StmtClass(n *ast.StmtClass) { f.addFreeFloating(token.T_WHITESPACE, []byte(" ")) if n.Extends != nil { + n.ExtendsTkn = f.newToken(token.T_EXTENDS, []byte("extends")) n.Extends.Accept(f) f.addFreeFloating(token.T_WHITESPACE, []byte(" ")) } if n.Implements != nil { - n.Implements.Accept(f) + n.ImplementsTkn = f.newToken(token.T_IMPLEMENTS, []byte("implements")) + n.ImplementsSeparatorTkns = f.formatList(n.Implements, ',') f.addFreeFloating(token.T_WHITESPACE, []byte(" ")) } @@ -318,20 +320,6 @@ func (f *formatter) StmtClassConstList(n *ast.StmtClassConstList) { n.SemiColonTkn = f.newSemicolonTkn() } -func (f *formatter) StmtClassExtends(n *ast.StmtClassExtends) { - n.ExtendTkn = f.newToken(token.T_EXTENDS, []byte("extends")) - f.addFreeFloating(token.T_WHITESPACE, []byte(" ")) - - n.ClassName.Accept(f) -} - -func (f *formatter) StmtClassImplements(n *ast.StmtClassImplements) { - n.ImplementsTkn = f.newToken(token.T_IMPLEMENTS, []byte("implements")) - f.addFreeFloating(token.T_WHITESPACE, []byte(" ")) - - n.SeparatorTkns = f.formatList(n.InterfaceNames, ',') -} - func (f *formatter) StmtClassMethod(n *ast.StmtClassMethod) { for _, m := range n.Modifiers { m.Accept(f) @@ -677,7 +665,8 @@ func (f *formatter) StmtInterface(n *ast.StmtInterface) { f.addFreeFloating(token.T_WHITESPACE, []byte(" ")) if n.Extends != nil { - n.Extends.Accept(f) + n.ExtendsTkn = f.newToken(token.T_EXTENDS, []byte("extends")) + n.ExtendsSeparatorTkns = f.formatList(n.Extends, ',') f.addFreeFloating(token.T_WHITESPACE, []byte(" ")) } @@ -695,16 +684,6 @@ func (f *formatter) StmtInterface(n *ast.StmtInterface) { n.CloseCurlyBracketTkn = f.newToken('}', []byte("}")) } -func (f *formatter) StmtInterfaceExtends(n *ast.StmtInterfaceExtends) { - n.ExtendsTkn = f.newToken(token.T_EXTENDS, []byte("extends")) - f.addFreeFloating(token.T_WHITESPACE, []byte(" ")) - - n.SeparatorTkns = nil - if len(n.InterfaceNames) > 0 { - n.SeparatorTkns = f.formatList(n.InterfaceNames, ',') - } -} - func (f *formatter) StmtLabel(n *ast.StmtLabel) { n.LabelName.Accept(f) n.ColonTkn = f.newToken(':', []byte(":")) @@ -865,16 +844,6 @@ func (f *formatter) StmtTrait(n *ast.StmtTrait) { n.TraitName.Accept(f) f.addFreeFloating(token.T_WHITESPACE, []byte(" ")) - if n.Extends != nil { - n.Extends.Accept(f) - f.addFreeFloating(token.T_WHITESPACE, []byte(" ")) - } - - if n.Implements != nil { - n.Implements.Accept(f) - f.addFreeFloating(token.T_WHITESPACE, []byte(" ")) - } - n.OpenCurlyBracketTkn = f.newToken('{', []byte("{")) if len(n.Stmts) > 0 { diff --git a/pkg/ast/visitor/formatter_test.go b/pkg/ast/visitor/formatter_test.go index 9e59126..7c708bc 100644 --- a/pkg/ast/visitor/formatter_test.go +++ b/pkg/ast/visitor/formatter_test.go @@ -519,12 +519,10 @@ func TestFormatter_Class_Extends(t *testing.T) { ClassName: &ast.Identifier{ Value: []byte("foo"), }, - Extends: &ast.StmtClassExtends{ - ClassName: &ast.NameName{ - Parts: []ast.Vertex{ - &ast.NameNamePart{ - Value: []byte("bar"), - }, + Extends: &ast.NameName{ + Parts: []ast.Vertex{ + &ast.NameNamePart{ + Value: []byte("bar"), }, }, }, @@ -556,13 +554,11 @@ func TestFormatter_Class_Implements(t *testing.T) { ClassName: &ast.Identifier{ Value: []byte("foo"), }, - Implements: &ast.StmtClassImplements{ - InterfaceNames: []ast.Vertex{ - &ast.NameName{ - Parts: []ast.Vertex{ - &ast.NameNamePart{ - Value: []byte("bar"), - }, + Implements: []ast.Vertex{ + &ast.NameName{ + Parts: []ast.Vertex{ + &ast.NameNamePart{ + Value: []byte("bar"), }, }, }, @@ -669,69 +665,6 @@ func TestFormatter_StmtClassConstList_Modifier(t *testing.T) { } } -func TestFormatter_ClassExtends(t *testing.T) { - o := bytes.NewBufferString("") - - n := &ast.StmtClassExtends{ - ClassName: &ast.NameName{ - Parts: []ast.Vertex{ - &ast.NameNamePart{ - Value: []byte("foo"), - }, - }, - }, - } - - f := visitor.NewFormatter().WithState(visitor.FormatterStatePHP).WithIndent(1) - n.Accept(f) - - p := visitor.NewPrinter(o).WithState(visitor.PrinterStatePHP) - n.Accept(p) - - expected := `extends foo` - actual := o.String() - - if expected != actual { - t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual) - } -} - -func TestFormatter_ClassImplements(t *testing.T) { - o := bytes.NewBufferString("") - - n := &ast.StmtClassImplements{ - InterfaceNames: []ast.Vertex{ - &ast.NameName{ - Parts: []ast.Vertex{ - &ast.NameNamePart{ - Value: []byte("foo"), - }, - }, - }, - &ast.NameName{ - Parts: []ast.Vertex{ - &ast.NameNamePart{ - Value: []byte("bar"), - }, - }, - }, - }, - } - - f := visitor.NewFormatter().WithState(visitor.FormatterStatePHP).WithIndent(1) - n.Accept(f) - - p := visitor.NewPrinter(o).WithState(visitor.PrinterStatePHP) - n.Accept(p) - - expected := `implements foo, bar` - actual := o.String() - - if expected != actual { - t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual) - } -} - func TestFormatter_ClassMethod(t *testing.T) { o := bytes.NewBufferString("") @@ -1881,13 +1814,11 @@ func TestFormatter_StmtInterface_Extends(t *testing.T) { InterfaceName: &ast.Identifier{ Value: []byte("foo"), }, - Extends: &ast.StmtInterfaceExtends{ - InterfaceNames: []ast.Vertex{ - &ast.NameName{ - Parts: []ast.Vertex{ - &ast.NameNamePart{ - Value: []byte("bar"), - }, + Extends: []ast.Vertex{ + &ast.NameName{ + Parts: []ast.Vertex{ + &ast.NameNamePart{ + Value: []byte("bar"), }, }, }, @@ -1913,42 +1844,6 @@ func TestFormatter_StmtInterface_Extends(t *testing.T) { } } -func TestFormatter_StmtInterfaceExtends(t *testing.T) { - o := bytes.NewBufferString("") - - n := &ast.StmtInterfaceExtends{ - InterfaceNames: []ast.Vertex{ - &ast.NameName{ - Parts: []ast.Vertex{ - &ast.NameNamePart{ - Value: []byte("foo"), - }, - }, - }, - &ast.NameName{ - Parts: []ast.Vertex{ - &ast.NameNamePart{ - Value: []byte("bar"), - }, - }, - }, - }, - } - - f := visitor.NewFormatter().WithState(visitor.FormatterStatePHP).WithIndent(1) - n.Accept(f) - - p := visitor.NewPrinter(o).WithState(visitor.PrinterStatePHP) - n.Accept(p) - - expected := `extends foo, bar` - actual := o.String() - - if expected != actual { - t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual) - } -} - func TestFormatter_StmtLabel(t *testing.T) { o := bytes.NewBufferString("") @@ -2465,82 +2360,6 @@ func TestFormatter_StmtTrait(t *testing.T) { } } -func TestFormatter_StmtTrait_Extends(t *testing.T) { - o := bytes.NewBufferString("") - - n := &ast.StmtTrait{ - TraitName: &ast.Identifier{ - Value: []byte("foo"), - }, - Extends: &ast.StmtClassExtends{ - ClassName: &ast.NameName{ - Parts: []ast.Vertex{ - &ast.NameNamePart{ - Value: []byte("bar"), - }, - }, - }, - }, - Stmts: []ast.Vertex{ - &ast.StmtNop{}, - }, - } - - f := visitor.NewFormatter().WithState(visitor.FormatterStatePHP).WithIndent(1) - n.Accept(f) - - p := visitor.NewPrinter(o).WithState(visitor.PrinterStatePHP) - n.Accept(p) - - expected := `trait foo extends bar { - ; - }` - actual := o.String() - - if expected != actual { - t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual) - } -} - -func TestFormatter_StmtTrait_Implements(t *testing.T) { - o := bytes.NewBufferString("") - - n := &ast.StmtTrait{ - TraitName: &ast.Identifier{ - Value: []byte("foo"), - }, - Implements: &ast.StmtClassImplements{ - InterfaceNames: []ast.Vertex{ - &ast.NameName{ - Parts: []ast.Vertex{ - &ast.NameNamePart{ - Value: []byte("bar"), - }, - }, - }, - }, - }, - Stmts: []ast.Vertex{ - &ast.StmtNop{}, - }, - } - - f := visitor.NewFormatter().WithState(visitor.FormatterStatePHP).WithIndent(1) - n.Accept(f) - - p := visitor.NewPrinter(o).WithState(visitor.PrinterStatePHP) - n.Accept(p) - - expected := `trait foo implements bar { - ; - }` - actual := o.String() - - if expected != actual { - t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual) - } -} - func TestFormatter_StmtTraitMethodRef(t *testing.T) { o := bytes.NewBufferString("") diff --git a/pkg/ast/visitor/namespace_resolver.go b/pkg/ast/visitor/namespace_resolver.go index 9e4e6a2..7de7f68 100644 --- a/pkg/ast/visitor/namespace_resolver.go +++ b/pkg/ast/visitor/namespace_resolver.go @@ -73,11 +73,11 @@ func (nsr *NamespaceResolver) StmtGroupUse(n *ast.StmtGroupUse) { func (nsr *NamespaceResolver) StmtClass(n *ast.StmtClass) { if n.Extends != nil { - nsr.ResolveName(n.Extends.(*ast.StmtClassExtends).ClassName, "") + nsr.ResolveName(n.Extends, "") } if n.Implements != nil { - for _, interfaceName := range n.Implements.(*ast.StmtClassImplements).InterfaceNames { + for _, interfaceName := range n.Implements { nsr.ResolveName(interfaceName, "") } } @@ -89,7 +89,7 @@ func (nsr *NamespaceResolver) StmtClass(n *ast.StmtClass) { func (nsr *NamespaceResolver) StmtInterface(n *ast.StmtInterface) { if n.Extends != nil { - for _, interfaceName := range n.Extends.(*ast.StmtInterfaceExtends).InterfaceNames { + for _, interfaceName := range n.Extends { nsr.ResolveName(interfaceName, "") } } diff --git a/pkg/ast/visitor/namespace_resolver_test.go b/pkg/ast/visitor/namespace_resolver_test.go index 8a8bb14..8d7d5cb 100644 --- a/pkg/ast/visitor/namespace_resolver_test.go +++ b/pkg/ast/visitor/namespace_resolver_test.go @@ -401,13 +401,9 @@ func TestResolveClassName(t *testing.T) { class := &ast.StmtClass{ ClassName: &ast.Identifier{Value: []byte("A")}, - Extends: &ast.StmtClassExtends{ - ClassName: nameAB, - }, - Implements: &ast.StmtClassImplements{ - InterfaceNames: []ast.Vertex{ - nameBC, - }, + Extends: nameAB, + Implements: []ast.Vertex{ + nameBC, }, } @@ -436,11 +432,9 @@ func TestResolveInterfaceName(t *testing.T) { interfaceNode := &ast.StmtInterface{ InterfaceName: &ast.Identifier{Value: []byte("A")}, - Extends: &ast.StmtInterfaceExtends{ - InterfaceNames: []ast.Vertex{ - nameAB, - nameBC, - }, + Extends: []ast.Vertex{ + nameAB, + nameBC, }, } diff --git a/pkg/ast/visitor/null.go b/pkg/ast/visitor/null.go index f412369..a8ca90d 100644 --- a/pkg/ast/visitor/null.go +++ b/pkg/ast/visitor/null.go @@ -62,14 +62,6 @@ func (v *Null) StmtClassConstList(_ *ast.StmtClassConstList) { // do nothing } -func (v *Null) StmtClassExtends(_ *ast.StmtClassExtends) { - // do nothing -} - -func (v *Null) StmtClassImplements(_ *ast.StmtClassImplements) { - // do nothing -} - func (v *Null) StmtClassMethod(_ *ast.StmtClassMethod) { // do nothing } @@ -154,10 +146,6 @@ func (v *Null) StmtInterface(_ *ast.StmtInterface) { // do nothing } -func (v *Null) StmtInterfaceExtends(_ *ast.StmtInterfaceExtends) { - // do nothing -} - func (v *Null) StmtLabel(_ *ast.StmtLabel) { // do nothing } diff --git a/pkg/ast/visitor/printer.go b/pkg/ast/visitor/printer.go index ff82f60..88fffed 100644 --- a/pkg/ast/visitor/printer.go +++ b/pkg/ast/visitor/printer.go @@ -194,8 +194,10 @@ func (p *printer) StmtClass(n *ast.StmtClass) { p.printToken(n.OpenParenthesisTkn, p.ifNodeList(n.Arguments, []byte("("))) p.printSeparatedList(n.Arguments, n.SeparatorTkns, []byte(",")) p.printToken(n.CloseParenthesisTkn, p.ifNodeList(n.Arguments, []byte(")"))) + p.printToken(n.ExtendsTkn, p.ifNode(n.Extends, []byte("extends"))) p.printNode(n.Extends) - p.printNode(n.Implements) + 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("}")) @@ -208,16 +210,6 @@ func (p *printer) StmtClassConstList(n *ast.StmtClassConstList) { p.printToken(n.SemiColonTkn, []byte(";")) } -func (p *printer) StmtClassExtends(n *ast.StmtClassExtends) { - p.printToken(n.ExtendTkn, []byte("extends")) - p.printNode(n.ClassName) -} - -func (p *printer) StmtClassImplements(n *ast.StmtClassImplements) { - p.printToken(n.ImplementsTkn, []byte("implements")) - p.printSeparatedList(n.InterfaceNames, n.SeparatorTkns, []byte(",")) -} - func (p *printer) StmtClassMethod(n *ast.StmtClassMethod) { p.printList(n.Modifiers) p.printToken(n.FunctionTkn, []byte("function")) @@ -436,17 +428,13 @@ func (p *printer) StmtInlineHtml(n *ast.StmtInlineHtml) { func (p *printer) StmtInterface(n *ast.StmtInterface) { p.printToken(n.InterfaceTkn, []byte("interface")) p.printNode(n.InterfaceName) - p.printNode(n.Extends) + p.printToken(n.ExtendsTkn, p.ifNodeList(n.Extends, []byte("extends"))) + p.printSeparatedList(n.Extends, n.ExtendsSeparatorTkns, []byte(",")) p.printToken(n.OpenCurlyBracketTkn, []byte("{")) p.printList(n.Stmts) p.printToken(n.CloseCurlyBracketTkn, []byte("}")) } -func (p *printer) StmtInterfaceExtends(n *ast.StmtInterfaceExtends) { - p.printToken(n.ExtendsTkn, []byte("extends")) - p.printSeparatedList(n.InterfaceNames, n.SeparatorTkns, []byte(",")) -} - func (p *printer) StmtLabel(n *ast.StmtLabel) { p.printNode(n.LabelName) p.printToken(n.ColonTkn, []byte(":")) @@ -525,8 +513,6 @@ func (p *printer) StmtThrow(n *ast.StmtThrow) { func (p *printer) StmtTrait(n *ast.StmtTrait) { p.printToken(n.TraitTkn, []byte("trait")) p.printNode(n.TraitName) - p.printNode(n.Extends) - p.printNode(n.Implements) p.printToken(n.OpenCurlyBracketTkn, []byte("{")) p.printList(n.Stmts) p.printToken(n.CloseCurlyBracketTkn, []byte("}")) diff --git a/pkg/ast/visitor/printer_test.go b/pkg/ast/visitor/printer_test.go index 1d4bcb1..7735a52 100644 --- a/pkg/ast/visitor/printer_test.go +++ b/pkg/ast/visitor/printer_test.go @@ -29,11 +29,9 @@ func TestPrinterPrintFile(t *testing.T) { &ast.NameNamePart{Value: []byte("Bar")}, }, }, - Extends: &ast.StmtClassExtends{ - ClassName: &ast.NameName{ - Parts: []ast.Vertex{ - &ast.NameNamePart{Value: []byte("Baz")}, - }, + Extends: &ast.NameName{ + Parts: []ast.Vertex{ + &ast.NameNamePart{Value: []byte("Baz")}, }, }, Stmts: []ast.Vertex{ @@ -3255,14 +3253,10 @@ func TestPrinterPrintStmtClass(t *testing.T) { n := &ast.StmtClass{ Modifiers: []ast.Vertex{&ast.Identifier{Value: []byte("abstract")}}, ClassName: &ast.Identifier{Value: []byte("Foo")}, - Extends: &ast.StmtClassExtends{ - ClassName: &ast.NameName{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("Bar")}}}, - }, - Implements: &ast.StmtClassImplements{ - InterfaceNames: []ast.Vertex{ - &ast.NameName{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("Baz")}}}, - &ast.NameName{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("Quuz")}}}, - }, + Extends: &ast.NameName{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("Bar")}}}, + Implements: []ast.Vertex{ + &ast.NameName{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("Baz")}}}, + &ast.NameName{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("Quuz")}}}, }, Stmts: []ast.Vertex{ &ast.StmtClassConstList{ @@ -3307,14 +3301,10 @@ func TestPrinterPrintStmtAnonymousClass(t *testing.T) { }, }, }, - Extends: &ast.StmtClassExtends{ - ClassName: &ast.NameName{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("Bar")}}}, - }, - Implements: &ast.StmtClassImplements{ - InterfaceNames: []ast.Vertex{ - &ast.NameName{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("Baz")}}}, - &ast.NameName{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("Quuz")}}}, - }, + Extends: &ast.NameName{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("Bar")}}}, + Implements: []ast.Vertex{ + &ast.NameName{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("Baz")}}}, + &ast.NameName{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("Quuz")}}}, }, Stmts: []ast.Vertex{ &ast.StmtClassConstList{ @@ -4122,11 +4112,9 @@ func TestPrinterPrintInterface(t *testing.T) { p := visitor.NewPrinter(o).WithState(visitor.PrinterStatePHP) n := &ast.StmtInterface{ InterfaceName: &ast.NameName{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("Foo")}}}, - Extends: &ast.StmtInterfaceExtends{ - InterfaceNames: []ast.Vertex{ - &ast.NameName{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("Bar")}}}, - &ast.NameName{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("Baz")}}}, - }, + Extends: []ast.Vertex{ + &ast.NameName{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("Bar")}}}, + &ast.NameName{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("Baz")}}}, }, Stmts: []ast.Vertex{ &ast.StmtClassMethod{